diff --git a/_maps/map_files/generic/City_of_Cogs.dmm b/_maps/map_files/generic/City_of_Cogs.dmm index 9ef765aa28..aba6569fd9 100644 --- a/_maps/map_files/generic/City_of_Cogs.dmm +++ b/_maps/map_files/generic/City_of_Cogs.dmm @@ -80,10 +80,6 @@ }, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"az" = ( -/obj/structure/destructible/clockwork/eminence_spire, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) "aA" = ( /obj/machinery/door/airlock/clockwork/brass{ name = "Infirmary" @@ -168,21 +164,6 @@ /obj/effect/clockwork/sigil/transmission, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"ew" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/construct_chassis/cogscarab{ - pixel_y = 20 - }, -/obj/item/clockwork/construct_chassis/cogscarab{ - pixel_x = -7; - pixel_y = 6 - }, -/obj/item/clockwork/construct_chassis/cogscarab{ - pixel_x = 7; - pixel_y = 6 - }, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) "hY" = ( /obj/item/clockwork/alloy_shards/pinion_lock, /turf/open/floor/clockwork/reebe, @@ -208,10 +189,6 @@ /obj/item/storage/belt/utility/servant, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"vx" = ( -/obj/effect/clockwork/sigil/transmission, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) "wV" = ( /obj/item/clockwork/alloy_shards/large, /turf/open/indestructible/reebe_void/spawning/lattices, @@ -244,6 +221,10 @@ /obj/item/clockwork/alloy_shards/small, /turf/open/indestructible/reebe_void/spawning/lattices, /area/reebe) +"Ox" = ( +/obj/structure/destructible/clockwork/eminence_spire, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) "OB" = ( /obj/item/clockwork/component/geis_capacitor/fallen_armor, /turf/open/floor/clockwork/reebe, @@ -32770,7 +32751,7 @@ ae ae ag ah -ew +aL aj aj aj @@ -33284,8 +33265,8 @@ ab ab ae ai -az -vx +Ox +aj aj aj aE diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index faffea0e6e..ea48671d82 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -59,6 +59,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list( //Human sub-species #define isabductor(A) (is_species(A, /datum/species/abductor)) #define isgolem(A) (is_species(A, /datum/species/golem)) +#define isclockworkgolem(A) (is_species(A, /datum/species/golem/clockwork/no_scrap)) #define islizard(A) (is_species(A, /datum/species/lizard)) #define isplasmaman(A) (is_species(A, /datum/species/plasmaman)) #define ispodperson(A) (is_species(A, /datum/species/pod)) diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index ac86912c84..f0a8a4e2c6 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -284,6 +284,17 @@ GLOBAL_LIST_INIT(wisdoms, world.file2list("strings/wisdoms.txt")) GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks")) GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien)) +/proc/get_roundstart_languages() + var/list/languages = subtypesof(/datum/language) + var/list/roundstart_languages = list("None") //default option for the list + for(var/some_language in languages) + var/datum/language/language = some_language + if(initial(language.chooseable_roundstart)) + roundstart_languages[initial(language.name)] = some_language + return roundstart_languages + +GLOBAL_LIST_INIT(roundstart_languages, get_roundstart_languages()) + //SPECIES BODYPART LISTS //locked parts are those that your picked species requires to have //unlocked parts are those that anyone can choose on customisation regardless diff --git a/code/_onclick/hud/clockwork_marauder.dm b/code/_onclick/hud/clockwork_marauder.dm index 09f85db574..b1b24cc58b 100644 --- a/code/_onclick/hud/clockwork_marauder.dm +++ b/code/_onclick/hud/clockwork_marauder.dm @@ -3,7 +3,7 @@ var/obj/screen/blockchance var/obj/screen/counterchance -/datum/hud/marauder/New(mob/living/simple_animal/hostile/clockwork/marauder/guardian/owner) +/datum/hud/marauder/New(mob/living/simple_animal/hostile/clockwork/guardian/owner) ..() var/obj/screen/using @@ -24,7 +24,7 @@ hosthealth = null return ..() -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/create_mob_hud() +/mob/living/simple_animal/hostile/clockwork/guardian/create_mob_hud() if(client && !hud_used) hud_used = new /datum/hud/marauder(src, ui_style2icon(client.prefs.UI_style)) @@ -37,8 +37,8 @@ desc = "Emerge or Return." /obj/screen/marauder/emerge/Click() - if(istype(usr, /mob/living/simple_animal/hostile/clockwork/marauder/guardian)) - var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/G = usr + if(istype(usr, /mob/living/simple_animal/hostile/clockwork/guardian)) + var/mob/living/simple_animal/hostile/clockwork/guardian/G = usr if(G.is_in_host()) G.try_emerge() else diff --git a/code/datums/skills/modifiers/job.dm b/code/datums/skills/modifiers/job.dm index e989ab11e3..e751fbf120 100644 --- a/code/datums/skills/modifiers/job.dm +++ b/code/datums/skills/modifiers/job.dm @@ -34,3 +34,6 @@ /datum/skill_modifier/job/level/wiring/basic level_mod = JOB_SKILL_BASIC + +/datum/skill_modifier/job/level/dwarfy/blacksmithing + target_skills = /datum/skill/level/dwarfy/blacksmithing diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index 659149a123..23fd75f982 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -219,19 +219,3 @@ /datum/quirk/night_vision/on_spawn() var/mob/living/carbon/human/H = quirk_holder H.update_sight() - -/datum/quirk/multilingual - name = "Multi-Lingual" - desc = "You spent a portion of your life learning to understand an additional language. You may or may not be able to speak it based on your anatomy." - value = 1 - mob_trait = TRAIT_MULTILINGUAL - gain_text = "You've learned an extra language!" - lose_text = "You've forgotten your extra language." - -/datum/quirk/multilingual/post_add() - var/mob/living/carbon/human/H = quirk_holder - H.grant_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MULTILINGUAL) - -/datum/quirk/multilingual/remove() - var/mob/living/carbon/human/H = quirk_holder - H.remove_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MULTILINGUAL) diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 480e1966e9..2035b67b5e 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -469,7 +469,7 @@ //hijacking the minature first aids for hypospray boxes. <3 /obj/item/storage/hypospraykit name = "hypospray kit" - desc = "It's a kit containing a hypospray and specific treatment chemical-filled vials." + desc = "It's a kit designed for containing a hypospray and specific treatment chemical-filled vials." icon_state = "firstaid-mini" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index b868fb54c0..34370faa0a 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -144,7 +144,7 @@ to_chat(L, "\"You belong to me now.\"") if(!GLOB.application_scripture_unlocked) GLOB.application_scripture_unlocked = TRUE - hierophant_message("With the conversion of a new servant the Ark's power grows. Application scriptures are now available.") + hierophant_message("With the conversion of a new servant the Hierophant Network's power grows. Application scriptures are now available.") if(add_servant_of_ratvar(L)) L.log_message("conversion was done with a [sigil_name]", LOG_ATTACK, color="BE8700") if(iscarbon(L)) diff --git a/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm b/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm index 58ee73ef5b..2b2720dea3 100644 --- a/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm +++ b/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm @@ -196,4 +196,68 @@ CL.visible_message("[CL] materialises out of thin air!") new /obj/effect/temp_visual/ratvar/sigil/transmission(T,2) +//summons a soul vessel, which is the clockwork cult version of a soul shard. It acts like a posibrain and, as long as the target has a brain, a soul shard. +/datum/clockwork_rite/soul_vessel + name = "Rite of the Vessel" //The name of the rite + desc = "This rite is used to summon a soul vessel, a special posibrain that makes whoever has their brain put into it loyal to the Justiciar.,\ + When put into a cyborg shell, the created cyborg will automatically be a servant of Ratvar." + required_ingredients = list(/obj/item/stack/cable_coil, /obj/item/stock_parts/cell/, /obj/item/organ/cyberimp) + power_cost = 2500 //These things are pretty strong, I won't lie + requires_full_power = TRUE + cast_time = 50 + limit = INFINITE + rite_cast_sound = 'sound/magic/summon_guns.ogg' + +/datum/clockwork_rite/soul_vessel/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target) + . = ..() + if(!.) + return FALSE + var/obj/item/mmi/posibrain/soul_vessel/SV = new /obj/item/mmi/posibrain/soul_vessel(T) + SV.visible_message("[SV] materalizes out of thin air!") + new /obj/effect/temp_visual/ratvar/sigil/transmission(T,2) + + +/datum/clockwork_rite/cyborg_transform + name = "Rite of the Divine Form" + desc = "This rite is used to ascend into a cyborg, gaining unique scripture and a loadout that depends on which module is chosen. Consult the wiki for details on each cyborg module's loadout. Mutually exclusive to Enhanced Form." + required_ingredients = list(/obj/item/mmi/posibrain, /obj/item/stack/cable_coil, /obj/item/stock_parts/cell/super, /obj/item/bodypart/l_arm/robot, /obj/item/bodypart/r_arm/robot, /obj/item/bodypart/chest/robot, /obj/item/bodypart/head/robot, /obj/item/bodypart/r_leg/robot, /obj/item/bodypart/l_leg/robot) + power_cost = 20000 + requires_human = TRUE + requires_full_power = FALSE + cast_time = 100 + limit = INFINITE + rite_cast_sound = 'sound/magic/disable_tech.ogg' + +/datum/clockwork_rite/cyborg_transform/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target) + . = ..() + if(!.) + return FALSE + if(isclockworkgolem(target)) + return FALSE + target.visible_message("The robotic parts magnetize to [target], the new frame's eyes glowing in a brilliant yellow!") + var/mob/living/silicon/robot/R = target.Robotize() + R.cell = new /obj/item/stock_parts/cell/super(R)//takes one to use the rite to begin with + new /obj/effect/temp_visual/ratvar/sigil/transmission(T,2) + +/datum/clockwork_rite/golem_transform + name = "Rite of the Enhanced Form" + desc = "This rite is used to shed one's flesh to become a clockwork automaton, becoming immune to many environmental hazards as well as being more resilient to incoming damage. Mutually exclusive to Divine Form." + required_ingredients = list(/obj/item/mmi/posibrain, /obj/item/stock_parts/cell/super, /obj/item/bodypart/l_arm/robot, /obj/item/bodypart/r_arm/robot, /obj/item/bodypart/chest/robot, /obj/item/bodypart/head/robot, /obj/item/bodypart/r_leg/robot, /obj/item/bodypart/l_leg/robot) + power_cost = 20000 + requires_human = TRUE + requires_full_power = FALSE + cast_time = 100 + limit = INFINITE + rite_cast_sound = 'sound/magic/disable_tech.ogg' + + +/datum/clockwork_rite/golem_transform/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target) + . = ..() + if(!.) + return FALSE + target.visible_message("The robotic parts magnetize to [target], the humanoid shape's eye glowing with an inner flame!") + to_chat(target, "The rite's power warps your body into a clockwork form! You are now immune to many hazards, and your body is more robust against damage!") + target.set_species(/datum/species/golem/clockwork/no_scrap) + new /obj/effect/temp_visual/ratvar/sigil/transmission(T,2) + #undef INFINITE diff --git a/code/modules/antagonists/clockcult/clock_helpers/fabrication_helpers.dm b/code/modules/antagonists/clockcult/clock_helpers/fabrication_helpers.dm index b0259c460e..99d1142990 100644 --- a/code/modules/antagonists/clockcult/clock_helpers/fabrication_helpers.dm +++ b/code/modules/antagonists/clockcult/clock_helpers/fabrication_helpers.dm @@ -350,3 +350,22 @@ // Winter coat /obj/item/clothing/suit/hooded/wintercoat/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //four sheets of metal return list("operation_time" = 30, "new_obj_type" = /obj/item/clothing/suit/hooded/wintercoat/ratvar, "power_cost" = POWER_METAL * 4, "spawn_dir" = SOUTH) + +//tools +/obj/item/crowbar/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //1 metal rod each + return list("operation_time" = 2, "new_obj_type" = /obj/item/crowbar/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH) + +/obj/item/screwdriver/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return list("operation_time" = 2, "new_obj_type" = /obj/item/screwdriver/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH) + +/obj/item/weldingtool/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return list("operation_time" = 2, "new_obj_type" = /obj/item/weldingtool/experimental/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH) + +/obj/item/wirecutters/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return list("operation_time" = 2, "new_obj_type" = /obj/item/wirecutters/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH) + +/obj/item/wrench/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return list("operation_time" = 2, "new_obj_type" = /obj/item/wrench/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH) + +/obj/item/multitool/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return list("operation_time" = 2, "new_obj_type" = /obj/item/multitool/advanced/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH) diff --git a/code/modules/antagonists/clockcult/clock_items/clock_augments.dm b/code/modules/antagonists/clockcult/clock_items/clock_augments.dm index 2131aa7160..ff19e8891b 100644 --- a/code/modules/antagonists/clockcult/clock_items/clock_augments.dm +++ b/code/modules/antagonists/clockcult/clock_items/clock_augments.dm @@ -5,7 +5,7 @@ name = "clock-themed arm-mounted implant" var/clockwork_desc = "According to Ratvar, this really shouldn't exist. Tell Him about this immediately." syndicate_implant = TRUE - icon_state = "clock_arm_implant" + icon_state = "toolkit_implant" /obj/item/organ/cyberimp/arm/clockwork/ui_action_click() if(is_servant_of_ratvar(owner) || (obj_flags & EMAGGED)) //If you somehow manage to steal a clockie's implant AND have an emag AND manage to get it implanted for yourself, good on ya! diff --git a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm index dfda2bf152..d9938316b6 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm @@ -251,7 +251,9 @@ var/mob/camera/eminence/E = owner E.eminence_help() + /* + //Returns to the Ark - Commented out and replaced with obelisk_jump /datum/action/innate/eminence/ark_jump name = "Return to Ark" @@ -265,7 +267,7 @@ owner.playsound_local(owner, 'sound/magic/magic_missile.ogg', 50, TRUE) flash_color(owner, flash_color = "#AF0AAF", flash_time = 25) else - to_chat(owner, "There is no Ark!") + to_chat(owner, "There is no Ark!") */ //Warps to a chosen Obelisk diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm new file mode 100644 index 0000000000..5060f516c7 --- /dev/null +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm @@ -0,0 +1,432 @@ +//Clockwork guardian: Slow but with high damage, resides inside of a servant. Created via the Memory Allocation scripture. +/mob/living/simple_animal/hostile/clockwork/guardian + name = "clockwork guardian" + desc = "A slow, armored clockwork machine, blazing with magenta flames. It's armed with a gladius and shield, and stands ready by its master." + icon_state = "clockwork_guardian" + health = 300 + maxHealth = 300 + speed = 1 + obj_damage = 40 + melee_damage_lower = 20//ranged attacks are the way to go for fighting these + melee_damage_upper = 20 + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" + attack_sound = 'sound/weapons/bladeslice.ogg' + weather_immunities = list("lava") + movement_type = FLYING + AIStatus = AI_OFF //this has to be manually set so that the guardian doesn't start bashing the host, how annoying -_- + loot = list(/obj/structure/destructible/clockwork/taunting_trail) + var/true_name = "Meme Master 69" //Required to call forth the guardian + var/global/list/possible_true_names = list("Servant", "Warden", "Serf", "Page", "Usher", "Knave", "Vassal", "Escort") + var/mob/living/host //The mob that the guardian is living inside of + var/recovering = FALSE //If the guardian is recovering from recalling + var/blockchance = 17 //chance to block attacks entirely + var/counterchance = 30 //chance to counterattack after blocking + var/static/list/damage_heal_order = list(OXY, BURN, BRUTE, TOX) //we heal our host's damage in this order + light_color = "#AF0AAF" + light_range = 2 + light_power = 1.1 + playstyle_string = "You are a clockwork guardian, a living extension of Sevtug's will. As a guardian, you are somewhat slow, but may block attacks, \ + and have a chance to also counter blocked melee attacks for extra damage, in addition to being immune to extreme temperatures and pressures. \ + Your primary goal is to serve the creature that you are now a part of, as well as The Clockwork Justiciar, Ratvar. You can use The Hierophant Network to communicate silently with your master and their allies, \ + but can only exit if your master calls your true name or if they are exceptionally damaged. \ + \n\n\ + Stay near your host to protect and heal them; being too far from your host will rapidly cause you massive damage. Recall to your host if you are too weak and believe you cannot continue \ + fighting safely. As a final note, you should probably avoid harming any fellow servants of Ratvar." + +/mob/living/simple_animal/hostile/clockwork/guardian/Initialize() + . = ..() + true_name = pick(possible_true_names) + +/mob/living/simple_animal/hostile/clockwork/guardian/BiologicalLife(seconds, times_fired) + ..() + if(is_in_host()) + if(!is_servant_of_ratvar(host)) + emerge_from_host(FALSE, TRUE) + unbind_from_host() + return + if(!GLOB.ratvar_awakens && host.stat == DEAD) + death() + return + if(GLOB.ratvar_awakens) + adjustHealth(-50) + else + adjustHealth(-10) + if(!recovering) + heal_host() //also heal our host if inside of them and we aren't recovering + else if(health == maxHealth) + to_chat(src, "Your strength has returned. You can once again come forward!") + to_chat(host, "Your guardian is now strong enough to come forward again!") + recovering = FALSE + else + if(GLOB.ratvar_awakens) //If Ratvar is alive, guardians don't need a host and are downright impossible to kill + adjustHealth(-5) + heal_host() + else if(host) + if(!is_servant_of_ratvar(host)) + unbind_from_host() + return + if(host.stat == DEAD) + adjustHealth(50) + to_chat(src, "Your host is dead!") + return + if(z && host.z && z == host.z) + switch(get_dist(get_turf(src), get_turf(host))) + if(2) + adjustHealth(-1) + if(3) + //EQUILIBRIUM + if(4) + adjustHealth(1) + if(5) + adjustHealth(3) + if(6) + adjustHealth(6) + if(7) + adjustHealth(9) + if(8 to INFINITY) + adjustHealth(15) + to_chat(src, "You're too far from your host and rapidly taking damage!") + else //right next to or on top of host + adjustHealth(-2) + heal_host() //gradually heal host if nearby and host is very weak + else //well then, you're not even in the same zlevel + adjustHealth(15) + to_chat(src, "You're too far from your host and rapidly taking damage!") + +/mob/living/simple_animal/hostile/clockwork/guardian/death(gibbed) + emerge_from_host(FALSE, TRUE) + unbind_from_host() + visible_message("[src]'s equipment fades into a purple mist as the flames within sputter and dissipate.", \ + "Your equipment fades away. You feel a moment of confusion before your fragile form is annihilated.") + . = ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/Stat() + ..() + if(statpanel("Status")) + stat(null, "Current True Name: [true_name]") + stat(null, "Host: [host ? host : "NONE"]") + if(host) + var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) + if(iscarbon(host)) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) + stat(null, "Host Health: [resulthealth]%") + if(GLOB.ratvar_awakens) + stat(null, "You are [recovering ? "un" : ""]able to deploy!") + else + if(resulthealth > GUARDIAN_EMERGE_THRESHOLD) + stat(null, "You are [recovering ? "unable to deploy" : "able to deploy on hearing your True Name"]!") + else + stat(null, "You are [recovering ? "unable to deploy" : "able to deploy to protect your host"]!") + stat(null, "You do [melee_damage_upper] damage on melee attacks.") + +/mob/living/simple_animal/hostile/clockwork/guardian/Process_Spacemove(movement_dir = 0) + return 1 + +/mob/living/simple_animal/hostile/clockwork/guardian/proc/bind_to_host(mob/living/new_host) + if(!new_host) + return FALSE + host = new_host + var/datum/action/innate/summon_guardian/SG = new() + SG.linked_guardian = src + SG.Grant(host) + var/datum/action/innate/linked_minds/LM = new() + LM.linked_guardian = src + LM.Grant(host) + return TRUE + +/mob/living/simple_animal/hostile/clockwork/guardian/proc/unbind_from_host() + if(host) + for(var/datum/action/innate/summon_guardian/SG in host.actions) + qdel(SG) + for(var/datum/action/innate/linked_minds/LM in host.actions) + qdel(LM) + host = null + return TRUE + return FALSE + +//DAMAGE and FATIGUE +/mob/living/simple_animal/hostile/clockwork/guardian/proc/heal_host() + if(!host) + return + var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) + if(iscarbon(host)) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) + if(GLOB.ratvar_awakens || resulthealth <= GUARDIAN_EMERGE_THRESHOLD) + new /obj/effect/temp_visual/heal(host.loc, "#AF0AAF") + host.heal_ordered_damage(4, damage_heal_order) + +/mob/living/simple_animal/hostile/clockwork/guardian/adjustHealth(amount, updating_health = TRUE, forced = FALSE) + if(amount > 0) + for(var/mob/living/L in view(2, src)) + if(L.is_holding_item_of_type(/obj/item/nullrod)) + to_chat(src, "The presence of a brandished holy artifact weakens your armor!") + amount *= 4 //if a wielded null rod is nearby, it takes four times the health damage + break + . = ..() + if(src && updating_health) + update_health_hud() + update_stats() + +/mob/living/simple_animal/hostile/clockwork/guardian/update_health_hud() + if(hud_used && hud_used.healths) + if(istype(hud_used, /datum/hud)) + var/datum/hud/marauder/G = hud_used + var/resulthealth + if(host) + if(iscarbon(host)) + resulthealth = "[round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)]%" + else + resulthealth = "[round((host.health / host.maxHealth) * 100, 0.5)]%" + else + resulthealth = "NONE" + G.hosthealth.maptext = "
HOST
[resulthealth]
" + hud_used.healths.maptext = "
[round((health / maxHealth) * 100, 0.5)]%" + +/mob/living/simple_animal/hostile/clockwork/guardian/proc/update_stats() + if(GLOB.ratvar_awakens) + speed = 0 + melee_damage_lower = 20 + melee_damage_upper = 20 + attack_verb_continuous = "devastates" + else + var/healthpercent = (health/maxHealth) * 100 + switch(healthpercent) + if(100 to 70) //Bonuses to speed and damage at high health + speed = 0 + melee_damage_lower = 16 + melee_damage_upper = 16 + attack_verb_continuous = "viciously slashes" + if(70 to 40) + speed = initial(speed) + melee_damage_lower = initial(melee_damage_lower) + melee_damage_upper = initial(melee_damage_upper) + attack_verb_continuous = initial(attack_verb_continuous) + if(40 to 30) //Damage decrease, but not speed + speed = initial(speed) + melee_damage_lower = 10 + melee_damage_upper = 10 + attack_verb_continuous = "lightly slashes" + if(30 to 20) //Speed decrease + speed = 2 + melee_damage_lower = 8 + melee_damage_upper = 8 + attack_verb_continuous = "lightly slashes" + if(20 to 10) //Massive speed decrease and weak melee attacks + speed = 3 + melee_damage_lower = 6 + melee_damage_upper = 6 + attack_verb_continuous = "weakly slashes" + if(10 to 0) //We are super weak and going to die + speed = 4 + melee_damage_lower = 4 + melee_damage_upper = 4 + attack_verb_continuous = "taps" + +//ATTACKING, BLOCKING, and COUNTERING + +/mob/living/simple_animal/hostile/clockwork/guardian/AttackingTarget() + if(is_in_host()) + return FALSE + return ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/bullet_act(obj/item/projectile/Proj) + if(blockOrCounter(null, Proj)) + return + return ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/hitby(atom/movable/AM, skipcatch, hitpush, blocked, atom/movable/AM, datum/thrownthing/throwingdatum) + if(blockOrCounter(null, AM)) + return + return ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/attack_animal(mob/living/simple_animal/M) + if(istype(M, /mob/living/simple_animal/hostile/clockwork/guardian) || !blockOrCounter(M, M)) //we don't want infinite blockcounter loops if fighting another guardian + return ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/attack_paw(mob/living/carbon/monkey/M) + if(!blockOrCounter(M, M)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/attack_alien(mob/living/carbon/alien/humanoid/M) + if(!blockOrCounter(M, M)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/attack_slime(mob/living/simple_animal/slime/M) + if(!blockOrCounter(M, M)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/attack_hand(mob/living/carbon/human/M) + if(!blockOrCounter(M, M)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/nullrod) || !blockOrCounter(user, I)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/guardian/proc/blockOrCounter(mob/target, atom/textobject) + if(GLOB.ratvar_awakens) //if ratvar has woken, we block nearly everything at a very high chance + blockchance = 90 + counterchance = 90 + if(prob(blockchance)) + . = TRUE + if(target) + target.do_attack_animation(src) + target.DelayNextAction(CLICK_CD_MELEE) + blockchance = initial(blockchance) + playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 30, 1, 0, 1) //clang + visible_message("[src] blocks [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!", \ + "You block [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!") + if(target && Adjacent(target)) + if(prob(counterchance)) + counterchance = initial(counterchance) + var/previousattack_verb_continuous = attack_verb_continuous + attack_verb_continuous = "counters" + UnarmedAttack(target) + attack_verb_continuous = previousattack_verb_continuous + else + counterchance = min(counterchance + initial(counterchance), 100) + else + blockchance = min(blockchance + initial(blockchance), 100) + if(GLOB.ratvar_awakens) + blockchance = 90 + counterchance = 90 + +//COMMUNICATION and EMERGENCE +/* +/mob/living/simple_animal/hostile/clockwork/guardian/handle_inherent_channels(message, message_mode) + if(host && (is_in_host() || message_mode == MODE_BINARY)) + guardian_comms(message) + return TRUE + return ..() +*/ +/mob/living/simple_animal/hostile/clockwork/guardian/proc/guardian_comms(message) + var/name_part = "[src] ([true_name])" + message = "\"[message]\"" //Processed output + to_chat(src, "[name_part]: [message]") + to_chat(host, "[name_part]: [message]") + for(var/M in GLOB.mob_list) + if(isobserver(M)) + var/link = FOLLOW_LINK(M, src) + to_chat(M, "[link] [name_part] (to [findtextEx(host.name, host.real_name) ? "[host.name]" : "[host.real_name] (as [host.name])"]): [message] ") + return TRUE + +/mob/living/simple_animal/hostile/clockwork/guardian/proc/return_to_host() + if(is_in_host()) + return FALSE + if(!host) + to_chat(src, "You don't have a host!") + return FALSE + var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) + if(iscarbon(host)) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) + host.visible_message("[host]'s skin flashes magenta!", "You feel [true_name]'s consciousness settle in your mind.") + visible_message("[src] suddenly disappears!", "You return to [host].") + forceMove(host) + if(resulthealth > GUARDIAN_EMERGE_THRESHOLD && health != maxHealth) + recovering = TRUE + to_chat(src, "You have weakened and will need to recover before manifesting again!") + to_chat(host, "[true_name] has weakened and will need to recover before manifesting again!") + return TRUE + +/mob/living/simple_animal/hostile/clockwork/guardian/proc/try_emerge() + if(!host) + to_chat(src, "You don't have a host!") + return FALSE + if(!GLOB.ratvar_awakens) + var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) + if(iscarbon(host)) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) + if(host.stat != DEAD && resulthealth > GUARDIAN_EMERGE_THRESHOLD) //if above 20 health, fails + to_chat(src, "Your host must be at [GUARDIAN_EMERGE_THRESHOLD]% or less health to emerge like this!") + return FALSE + return emerge_from_host(FALSE) + +/mob/living/simple_animal/hostile/clockwork/guardian/proc/emerge_from_host(hostchosen, force) //Notice that this is a proc rather than a verb - guardians can NOT exit at will, but they CAN return + if(!is_in_host()) + return FALSE + if(!force && recovering) + if(hostchosen) + to_chat(host, "[true_name] is too weak to come forth!") + else + to_chat(host, "[true_name] tries to emerge to protect you, but it's too weak!") + to_chat(src, "You try to come forth, but you're too weak!") + return FALSE + if(!force) + if(hostchosen) //guardian approved + to_chat(host, "Your words echo with power as [true_name] emerges from your body!") + else + to_chat(host, "[true_name] emerges from your body to protect you!") + forceMove(host.loc) + visible_message("[host]'s skin glows red as [name] emerges from their body!", "You exit the safety of [host]'s body!") + return TRUE + +/mob/living/simple_animal/hostile/clockwork/guardian/get_alt_name() + return " ([text2ratvar(true_name)])" + +/mob/living/simple_animal/hostile/clockwork/guardian/proc/is_in_host() //Checks if the guardian is inside of their host + return host && loc == host + +//HOST ACTIONS + +//Summon guardian action: Calls forth or recalls your guardian +/datum/action/innate/summon_guardian + name = "Force Guardian to Emerge/Recall" + desc = "Allows you to force your clockwork guardian to emerge or recall as required." + button_icon_state = "clockwork_marauder" + background_icon_state = "bg_clock" + check_flags = AB_CHECK_CONSCIOUS + buttontooltipstyle = "clockcult" + var/mob/living/simple_animal/hostile/clockwork/guardian/linked_guardian + var/list/defend_phrases = list("Defend me", "Come forth", "Assist me", "Protect me", "Give aid", "Help me") + var/list/return_phrases = list("Return", "Return to me", "Your job is done", "You have served", "Come back", "Retreat") + +/datum/action/innate/summon_guardian/IsAvailable() + if(!linked_guardian) + return FALSE + if(isliving(owner)) + var/mob/living/L = owner + if(!L.can_speak_vocal() || L.stat) + return FALSE + return ..() + +/datum/action/innate/summon_guardian/Activate() + if(linked_guardian.is_in_host()) + clockwork_say(owner, text2ratvar("[pick(defend_phrases)], [linked_guardian.true_name]!")) + linked_guardian.emerge_from_host(TRUE) + else + clockwork_say(owner, text2ratvar("[pick(return_phrases)], [linked_guardian.true_name]!")) + linked_guardian.return_to_host() + return TRUE + +//Linked Minds action: talks to your guardian +/datum/action/innate/linked_minds + name = "Linked Minds" + desc = "Allows you to silently communicate with your guardian." + button_icon_state = "linked_minds" + background_icon_state = "bg_clock" + check_flags = AB_CHECK_CONSCIOUS + buttontooltipstyle = "clockcult" + var/mob/living/simple_animal/hostile/clockwork/guardian/linked_guardian + +/datum/action/innate/linked_minds/IsAvailable() + if(!linked_guardian) + return FALSE + return ..() + +/datum/action/innate/linked_minds/Activate() + var/message = stripped_input(owner, "Enter a message to tell your guardian.", "Telepathy") + if(!owner || !message) + return FALSE + if(!linked_guardian) + to_chat(owner, "Your guardian seems to have been destroyed!") + return FALSE + var/name_part = "Servant [findtextEx(owner.name, owner.real_name) ? "[owner.name]" : "[owner.real_name] (as [owner.name])"]" + message = "\"[message]\"" //Processed output + to_chat(owner, "[name_part]: [message]") + to_chat(linked_guardian, "[name_part]: [message]") + for(var/M in GLOB.mob_list) + if(isobserver(M)) + var/link = FOLLOW_LINK(M, src) + to_chat(M, "[link] [name_part] (to [linked_guardian] ([linked_guardian.true_name])): [message]") + return TRUE diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm index 76c9db7231..d58608652c 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm @@ -123,437 +123,3 @@ #undef MARAUDER_SLOWDOWN_PERCENTAGE #undef MARAUDER_SHIELD_REGEN_TIME - -//Clockwork guardian: Slow but with high damage, resides inside of a servant. Created via the Memory Allocation scripture. -/mob/living/simple_animal/hostile/clockwork/marauder/guardian - name = "clockwork guardian" - desc = "A stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield and stands ready by its master." - icon_state = "clockwork_marauder" - health = 300 - maxHealth = 300 - speed = 1 - obj_damage = 40 - melee_damage_lower = 12 - melee_damage_upper = 12 - attack_verb_continuous = "slashes" - attack_verb_simple = "slash" - attack_sound = 'sound/weapons/bladeslice.ogg' - weather_immunities = list("lava") - movement_type = FLYING - AIStatus = AI_OFF //this has to be manually set so that the guardian doesn't start bashing the host, how annoying -_- - loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor) - max_shield_health = 0 - shield_health = 0 - var/true_name = "Meme Master 69" //Required to call forth the guardian - var/global/list/possible_true_names = list("Servant", "Warden", "Serf", "Page", "Usher", "Knave", "Vassal", "Escort") - var/mob/living/host //The mob that the guardian is living inside of - var/recovering = FALSE //If the guardian is recovering from recalling - var/blockchance = 17 //chance to block attacks entirely - var/counterchance = 30 //chance to counterattack after blocking - var/static/list/damage_heal_order = list(OXY, BURN, BRUTE, TOX) //we heal our host's damage in this order - light_range = 2 - light_power = 1.1 - playstyle_string = "You are a clockwork guardian, a living extension of Sevtug's will. As a guardian, you are somewhat slow, but may block attacks, \ - and have a chance to also counter blocked melee attacks for extra damage, in addition to being immune to extreme temperatures and pressures. \ - Your primary goal is to serve the creature that you are now a part of, as well as The Clockwork Justiciar, Ratvar. You can use The Hierophant Network to communicate silently with your master and their allies, \ - but can only exit if your master calls your true name or if they are exceptionally damaged. \ - \n\n\ - Stay near your host to protect and heal them; being too far from your host will rapidly cause you massive damage. Recall to your host if you are too weak and believe you cannot continue \ - fighting safely. As a final note, you should probably avoid harming any fellow servants of Ratvar." - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Initialize() - . = ..() - true_name = pick(possible_true_names) - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/BiologicalLife(seconds, times_fired) - ..() - if(is_in_host()) - if(!is_servant_of_ratvar(host)) - emerge_from_host(FALSE, TRUE) - unbind_from_host() - return - if(!GLOB.ratvar_awakens && host.stat == DEAD) - death() - return - if(GLOB.ratvar_awakens) - adjustHealth(-50) - else - adjustHealth(-10) - if(!recovering) - heal_host() //also heal our host if inside of them and we aren't recovering - else if(health == maxHealth) - to_chat(src, "Your strength has returned. You can once again come forward!") - to_chat(host, "Your guardian is now strong enough to come forward again!") - recovering = FALSE - else - if(GLOB.ratvar_awakens) //If Ratvar is alive, guardians don't need a host and are downright impossible to kill - adjustHealth(-5) - heal_host() - else if(host) - if(!is_servant_of_ratvar(host)) - unbind_from_host() - return - if(host.stat == DEAD) - adjustHealth(50) - to_chat(src, "Your host is dead!") - return - if(z && host.z && z == host.z) - switch(get_dist(get_turf(src), get_turf(host))) - if(2) - adjustHealth(-1) - if(3) - //EQUILIBRIUM - if(4) - adjustHealth(1) - if(5) - adjustHealth(3) - if(6) - adjustHealth(6) - if(7) - adjustHealth(9) - if(8 to INFINITY) - adjustHealth(15) - to_chat(src, "You're too far from your host and rapidly taking damage!") - else //right next to or on top of host - adjustHealth(-2) - heal_host() //gradually heal host if nearby and host is very weak - else //well then, you're not even in the same zlevel - adjustHealth(15) - to_chat(src, "You're too far from your host and rapidly taking damage!") - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/death(gibbed) - emerge_from_host(FALSE, TRUE) - unbind_from_host() - visible_message("[src]'s equipment clatters lifelessly to the ground as the red flames within dissipate.", \ - "Your equipment falls away. You feel a moment of confusion before your fragile form is annihilated.") - . = ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Stat() - ..() - if(statpanel("Status")) - stat(null, "Current True Name: [true_name]") - stat(null, "Host: [host ? host : "NONE"]") - if(host) - var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) - if(iscarbon(host)) - resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) - stat(null, "Host Health: [resulthealth]%") - if(GLOB.ratvar_awakens) - stat(null, "You are [recovering ? "un" : ""]able to deploy!") - else - if(resulthealth > GUARDIAN_EMERGE_THRESHOLD) - stat(null, "You are [recovering ? "unable to deploy" : "able to deploy on hearing your True Name"]!") - else - stat(null, "You are [recovering ? "unable to deploy" : "able to deploy to protect your host"]!") - stat(null, "You do [melee_damage_upper] damage on melee attacks.") - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Process_Spacemove(movement_dir = 0) - return 1 - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/bind_to_host(mob/living/new_host) - if(!new_host) - return FALSE - host = new_host - var/datum/action/innate/summon_guardian/SG = new() - SG.linked_guardian = src - SG.Grant(host) - var/datum/action/innate/linked_minds/LM = new() - LM.linked_guardian = src - LM.Grant(host) - return TRUE - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/unbind_from_host() - if(host) - for(var/datum/action/innate/summon_guardian/SG in host.actions) - qdel(SG) - for(var/datum/action/innate/linked_minds/LM in host.actions) - qdel(LM) - host = null - return TRUE - return FALSE - -//DAMAGE and FATIGUE -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/heal_host() - if(!host) - return - var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) - if(iscarbon(host)) - resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) - if(GLOB.ratvar_awakens || resulthealth <= GUARDIAN_EMERGE_THRESHOLD) - new /obj/effect/temp_visual/heal(host.loc, "#AF0AAF") - host.heal_ordered_damage(4, damage_heal_order) - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/adjustHealth(amount, updating_health = TRUE, forced = FALSE) - if(amount > 0) - for(var/mob/living/L in view(2, src)) - if(L.is_holding_item_of_type(/obj/item/nullrod)) - to_chat(src, "The presence of a brandished holy artifact weakens your armor!") - amount *= 4 //if a wielded null rod is nearby, it takes four times the health damage - break - . = ..() - if(src && updating_health) - update_health_hud() - update_stats() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/update_health_hud() - if(hud_used && hud_used.healths) - if(istype(hud_used, /datum/hud/marauder)) - var/datum/hud/marauder/G = hud_used - var/resulthealth - if(host) - if(iscarbon(host)) - resulthealth = "[round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)]%" - else - resulthealth = "[round((host.health / host.maxHealth) * 100, 0.5)]%" - else - resulthealth = "NONE" - G.hosthealth.maptext = "
HOST
[resulthealth]
" - hud_used.healths.maptext = "
[round((health / maxHealth) * 100, 0.5)]%" - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/update_stats() - if(GLOB.ratvar_awakens) - speed = 0 - melee_damage_lower = 20 - melee_damage_upper = 20 - attack_verb_continuous = "devastates" - else - var/healthpercent = (health/maxHealth) * 100 - switch(healthpercent) - if(100 to 70) //Bonuses to speed and damage at high health - speed = 0 - melee_damage_lower = 16 - melee_damage_upper = 16 - attack_verb_continuous = "viciously slashes" - if(70 to 40) - speed = initial(speed) - melee_damage_lower = initial(melee_damage_lower) - melee_damage_upper = initial(melee_damage_upper) - attack_verb_continuous = initial(attack_verb_continuous) - if(40 to 30) //Damage decrease, but not speed - speed = initial(speed) - melee_damage_lower = 10 - melee_damage_upper = 10 - attack_verb_continuous = "lightly slashes" - if(30 to 20) //Speed decrease - speed = 2 - melee_damage_lower = 8 - melee_damage_upper = 8 - attack_verb_continuous = "lightly slashes" - if(20 to 10) //Massive speed decrease and weak melee attacks - speed = 3 - melee_damage_lower = 6 - melee_damage_upper = 6 - attack_verb_continuous = "weakly slashes" - if(10 to 0) //We are super weak and going to die - speed = 4 - melee_damage_lower = 4 - melee_damage_upper = 4 - attack_verb_continuous = "taps" - -//ATTACKING, BLOCKING, and COUNTERING - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/AttackingTarget() - if(is_in_host()) - return FALSE - return ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/bullet_act(obj/item/projectile/Proj) - if(blockOrCounter(null, Proj)) - return - return ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/hitby(atom/movable/AM, skipcatch, hitpush, blocked, atom/movable/AM, datum/thrownthing/throwingdatum) - if(blockOrCounter(null, AM)) - return - return ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_animal(mob/living/simple_animal/M) - if(istype(M, /mob/living/simple_animal/hostile/clockwork/marauder/guardian) || !blockOrCounter(M, M)) //we don't want infinite blockcounter loops if fighting another guardian - return ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_paw(mob/living/carbon/monkey/M) - if(!blockOrCounter(M, M)) - return ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_alien(mob/living/carbon/alien/humanoid/M) - if(!blockOrCounter(M, M)) - return ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_slime(mob/living/simple_animal/slime/M) - if(!blockOrCounter(M, M)) - return ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_hand(mob/living/carbon/human/M) - if(!blockOrCounter(M, M)) - return ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/nullrod) || !blockOrCounter(user, I)) - return ..() - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/blockOrCounter(mob/target, atom/textobject) - if(GLOB.ratvar_awakens) //if ratvar has woken, we block nearly everything at a very high chance - blockchance = 90 - counterchance = 90 - if(prob(blockchance)) - . = TRUE - if(target) - target.do_attack_animation(src) - target.DelayNextAction(CLICK_CD_MELEE) - blockchance = initial(blockchance) - playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 30, 1, 0, 1) //clang - visible_message("[src] blocks [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!", \ - "You block [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!") - if(target && Adjacent(target)) - if(prob(counterchance)) - counterchance = initial(counterchance) - var/previousattack_verb_continuous = attack_verb_continuous - attack_verb_continuous = "counters" - UnarmedAttack(target) - attack_verb_continuous = previousattack_verb_continuous - else - counterchance = min(counterchance + initial(counterchance), 100) - else - blockchance = min(blockchance + initial(blockchance), 100) - if(GLOB.ratvar_awakens) - blockchance = 90 - counterchance = 90 - -//COMMUNICATION and EMERGENCE -/* -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/handle_inherent_channels(message, message_mode) - if(host && (is_in_host() || message_mode == MODE_BINARY)) - guardian_comms(message) - return TRUE - return ..() -*/ -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/guardian_comms(message) - var/name_part = "[src] ([true_name])" - message = "\"[message]\"" //Processed output - to_chat(src, "[name_part]: [message]") - to_chat(host, "[name_part]: [message]") - for(var/M in GLOB.mob_list) - if(isobserver(M)) - var/link = FOLLOW_LINK(M, src) - to_chat(M, "[link] [name_part] (to [findtextEx(host.name, host.real_name) ? "[host.name]" : "[host.real_name] (as [host.name])"]): [message] ") - return TRUE - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/return_to_host() - if(is_in_host()) - return FALSE - if(!host) - to_chat(src, "You don't have a host!") - return FALSE - var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) - if(iscarbon(host)) - resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) - host.visible_message("[host]'s skin flashes crimson!", "You feel [true_name]'s consciousness settle in your mind.") - visible_message("[src] suddenly disappears!", "You return to [host].") - forceMove(host) - if(resulthealth > GUARDIAN_EMERGE_THRESHOLD && health != maxHealth) - recovering = TRUE - to_chat(src, "You have weakened and will need to recover before manifesting again!") - to_chat(host, "[true_name] has weakened and will need to recover before manifesting again!") - return TRUE - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/try_emerge() - if(!host) - to_chat(src, "You don't have a host!") - return FALSE - if(!GLOB.ratvar_awakens) - var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) - if(iscarbon(host)) - resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) - if(host.stat != DEAD && resulthealth > GUARDIAN_EMERGE_THRESHOLD) //if above 20 health, fails - to_chat(src, "Your host must be at [GUARDIAN_EMERGE_THRESHOLD]% or less health to emerge like this!") - return FALSE - return emerge_from_host(FALSE) - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/emerge_from_host(hostchosen, force) //Notice that this is a proc rather than a verb - guardians can NOT exit at will, but they CAN return - if(!is_in_host()) - return FALSE - if(!force && recovering) - if(hostchosen) - to_chat(host, "[true_name] is too weak to come forth!") - else - to_chat(host, "[true_name] tries to emerge to protect you, but it's too weak!") - to_chat(src, "You try to come forth, but you're too weak!") - return FALSE - if(!force) - if(hostchosen) //guardian approved - to_chat(host, "Your words echo with power as [true_name] emerges from your body!") - else - to_chat(host, "[true_name] emerges from your body to protect you!") - forceMove(host.loc) - visible_message("[host]'s skin glows red as [name] emerges from their body!", "You exit the safety of [host]'s body!") - return TRUE - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/get_alt_name() - return " ([text2ratvar(true_name)])" - -/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/is_in_host() //Checks if the guardian is inside of their host - return host && loc == host - -//HOST ACTIONS - -//Summon guardian action: Calls forth or recalls your guardian -/datum/action/innate/summon_guardian - name = "Force Guardian to Emerge/Recall" - desc = "Allows you to force your clockwork guardian to emerge or recall as required." - button_icon_state = "clockwork_marauder" - background_icon_state = "bg_clock" - check_flags = AB_CHECK_CONSCIOUS - buttontooltipstyle = "clockcult" - var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/linked_guardian - var/list/defend_phrases = list("Defend me", "Come forth", "Assist me", "Protect me", "Give aid", "Help me") - var/list/return_phrases = list("Return", "Return to me", "Your job is done", "You have served", "Come back", "Retreat") - -/datum/action/innate/summon_guardian/IsAvailable() - if(!linked_guardian) - return FALSE - if(isliving(owner)) - var/mob/living/L = owner - if(!L.can_speak_vocal() || L.stat) - return FALSE - return ..() - -/datum/action/innate/summon_guardian/Activate() - if(linked_guardian.is_in_host()) - clockwork_say(owner, text2ratvar("[pick(defend_phrases)], [linked_guardian.true_name]!")) - linked_guardian.emerge_from_host(TRUE) - else - clockwork_say(owner, text2ratvar("[pick(return_phrases)], [linked_guardian.true_name]!")) - linked_guardian.return_to_host() - return TRUE - -//Linked Minds action: talks to your guardian -/datum/action/innate/linked_minds - name = "Linked Minds" - desc = "Allows you to silently communicate with your guardian." - button_icon_state = "linked_minds" - background_icon_state = "bg_clock" - check_flags = AB_CHECK_CONSCIOUS - buttontooltipstyle = "clockcult" - var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/linked_guardian - -/datum/action/innate/linked_minds/IsAvailable() - if(!linked_guardian) - return FALSE - return ..() - -/datum/action/innate/linked_minds/Activate() - var/message = stripped_input(owner, "Enter a message to tell your guardian.", "Telepathy") - if(!owner || !message) - return FALSE - if(!linked_guardian) - to_chat(owner, "Your guardian seems to have been destroyed!") - return FALSE - var/name_part = "Servant [findtextEx(owner.name, owner.real_name) ? "[owner.name]" : "[owner.real_name] (as [owner.name])"]" - message = "\"[message]\"" //Processed output - to_chat(owner, "[name_part]: [message]") - to_chat(linked_guardian, "[name_part]: [message]") - for(var/M in GLOB.mob_list) - if(isobserver(M)) - var/link = FOLLOW_LINK(M, src) - to_chat(M, "[link] [name_part] (to [linked_guardian] ([linked_guardian.true_name])): [message]") - return TRUE diff --git a/code/modules/antagonists/clockcult/clock_scripture.dm b/code/modules/antagonists/clockcult/clock_scripture.dm index aa0f7f03fa..6922c7cd81 100644 --- a/code/modules/antagonists/clockcult/clock_scripture.dm +++ b/code/modules/antagonists/clockcult/clock_scripture.dm @@ -5,7 +5,7 @@ Pieces of scripture require certain follower counts, contruction value, and acti Drivers: Unlocked by default Scripts: 35k power or one convert Applications: 50k or three converts -Judgement 5 converts +Judgement 80k power or nine converts */ /datum/clockwork_scripture diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm index 77dc174238..85450dc152 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm @@ -18,7 +18,7 @@ tier = SCRIPTURE_APPLICATION one_per_tile = TRUE primary_component = HIEROPHANT_ANSIBLE - sort_priority = 1 + sort_priority = 2 important = TRUE quickbind = TRUE quickbind_desc = "Creates a Sigil of Transmission, which can drain and will store power for clockwork structures." @@ -72,7 +72,7 @@ tier = SCRIPTURE_APPLICATION one_per_tile = TRUE primary_component = HIEROPHANT_ANSIBLE - sort_priority = 2 + sort_priority = 5 quickbind = TRUE quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants." requires_full_power = TRUE @@ -101,7 +101,7 @@ //Memory Allocation: Finds a willing ghost and makes them into a clockwork guardian for the invoker. /datum/clockwork_scripture/memory_allocation - descname = "Personal Guardian, A Peice Of Your Mind." + descname = "Personal Guardian housed in the brain." name = "Memory Allocation" desc = "Allocates part of your consciousness to a Clockwork Guardian, a variant of Marauder that lives within you, able to be \ called forth by Speaking its True Name or if you become exceptionally low on health.
\ @@ -109,13 +109,13 @@ invocations = list("Fright's will...", "...call forth...") channel_time = 100 power_cost = 8000 - usage_tip = "guardians are useful as personal bodyguards and frontline warriors." + usage_tip = "Guardians are useful as personal bodyguards and frontline warriors." tier = SCRIPTURE_APPLICATION primary_component = GEIS_CAPACITOR - sort_priority = 5 + sort_priority = 6 /datum/clockwork_scripture/memory_allocation/check_special_requirements() - for(var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/M in GLOB.all_clockwork_mobs) + for(var/mob/living/simple_animal/hostile/clockwork/guardian/M in GLOB.all_clockwork_mobs) if(M.host == invoker) to_chat(invoker, "You can only house one guardian at a time!") return FALSE @@ -151,7 +151,7 @@ return FALSE clockwork_say(invoker, text2ratvar("...sword and shield!")) var/mob/dead/observer/theghost = pick(marauder_candidates) - var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/M = new(invoker) + var/mob/living/simple_animal/hostile/clockwork/guardian/M = new(invoker) M.key = theghost.key M.bind_to_host(invoker) invoker.visible_message("The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!", \ @@ -171,7 +171,7 @@ tier = SCRIPTURE_APPLICATION one_per_tile = TRUE primary_component = BELLIGERENT_EYE - sort_priority = 6 + sort_priority = 7 quickbind = TRUE quickbind_desc = "Creates a clockwork marauder, used for frontline combat." object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder @@ -223,7 +223,7 @@ object_path = /obj/mecha/combat/neovgre tier = SCRIPTURE_APPLICATION primary_component = BELLIGERENT_EYE - sort_priority = 7 + sort_priority = 8 creator_message = "Neovgre, the Anima Bulwark towers over you... your enemies reckoning has come." /datum/clockwork_scripture/create_object/summon_arbiter/check_special_requirements() diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm index 5075840e76..ea10725489 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm @@ -20,7 +20,7 @@ usage_tip = "The gateway is completely vulnerable to attack during its five-minute duration. It will periodically give indication of its general position to everyone on the station \ as well as being loud enough to be heard throughout the entire sector. Defend it with your life!" tier = SCRIPTURE_APPLICATION - sort_priority = 8 + sort_priority = 1 requires_full_power = TRUE /datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar/check_special_requirements() diff --git a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm index 3b507fb57c..a481415cf5 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm @@ -81,7 +81,7 @@ priority_announce("Massive [Gibberish("bluespace", 100)] anomaly detected on all frequencies. All crew are directed to \ @!$, [text2ratvar("PURGE ALL UNTRUTHS")] <&. the anomalies and destroy their source to prevent further damage to corporate property. This is \ not a drill.", "Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation_sequence.ogg') - set_security_level("delta") + set_security_level("Delta") for(var/V in SSticker.mode.servants_of_ratvar) var/datum/mind/M = V if(!M || !M.current) diff --git a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm index 28901ea0b2..24ad1af88a 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm @@ -29,8 +29,9 @@ sound_to_playing_players('sound/effects/ratvar_reveal.ogg') 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 + INVOKE_ASYNC(src, .proc/purge_the_heresy) + /obj/structure/destructible/clockwork/massive/ratvar/Destroy() GLOB.ratvar_awakens-- @@ -151,3 +152,34 @@ sound_to_playing_players('sound/machines/clockcult/ratvar_scream.ogg', 80) narsie.clashing = FALSE qdel(src) + + +/obj/structure/destructible/clockwork/massive/ratvar/proc/purge_the_heresy() + sleep(50) + priority_announce("Massive energy surge detected. Closest matching threat: Incoming supernova. All crew are advised to evacuate NAN lightyears away from blast zone","Central Command Higher Dimensional Affairs", 'sound/misc/airraid.ogg') + sleep(300) + priority_announce("Gravitational anomalies detected on the station. [Gibberish("There is no additional dat", 100)]-BZZZZZT.","Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ratvar_announce1.ogg') + sleep(80) + sound_to_playing_players('sound/magic/clockwork/ratvar_announce2.ogg', 70) + send_to_playing_players("\"COME, ALL THOSE FAITHFUL! WITNESS THE RAYS OF JUSTICE CAST UPON THE HERETICS!\"") + sleep(50) + SSshuttle.registerHostileEnvironment(src) + SSshuttle.lockdown = TRUE + sleep(250) + if(QDELETED(src)) + priority_announce("Energy signal no longer detected.","Central Command Higher Dimensional Affairs") + return + sound_to_playing_players('sound/magic/clockwork/ark_activation_sequence.ogg', 80) //if this isn't lessened in volume it peaks for some reason + addtimer(CALLBACK(GLOBAL_PROC, /proc/clockcult_ending_helper), 300) + +/proc/clockcult_ending_helper() + for(var/mob/M in GLOB.mob_list) + if(M.client) + SEND_SOUND(M, sound('sound/magic/clockwork/ratvar_attack.ogg')) + SEND_SOUND(M, sound('sound/magic/clockwork/ratvarfire.ogg')) + if(!is_servant_of_ratvar(M) && isliving(M)) + var/mob/living/L = M + L.fire_stacks = INFINITY + L.IgniteMob() + sleep(50) + SSticker.force_ending = 1 diff --git a/code/modules/antagonists/clockcult/clock_structures/reflector.dm b/code/modules/antagonists/clockcult/clock_structures/reflector.dm index c91e9dd918..e734429524 100644 --- a/code/modules/antagonists/clockcult/clock_structures/reflector.dm +++ b/code/modules/antagonists/clockcult/clock_structures/reflector.dm @@ -1,7 +1,7 @@ /obj/structure/destructible/clockwork/reflector name = "reflector" - desc = "A large lantern-shaped machine made of thin brass. It looks fragile." - clockwork_desc = "A lantern-shaped generator that produces power when near starlight." + desc = "A large mirror-like structure made of thin brass on one side. It looks fragile." + clockwork_desc = "A large mirror-like structure made of thin brass on one side. It can redirect laser fire on one side" icon_state = "reflector" unanchored_icon = "reflector_unwrenched" max_integrity = 40 diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm index b935258c27..efea8ed771 100644 --- a/code/modules/antagonists/clockcult/clockcult.dm +++ b/code/modules/antagonists/clockcult/clockcult.dm @@ -5,7 +5,7 @@ antagpanel_category = "Clockcult" job_rank = ROLE_SERVANT_OF_RATVAR antag_moodlet = /datum/mood_event/cult - skill_modifiers = list(/datum/skill_modifier/job/level/wiring) + skill_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/level/dwarfy/blacksmithing) var/datum/action/innate/hierophant/hierophant_network = new threat = 3 var/datum/team/clockcult/clock_team diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm index 77893225fa..bbdf41ff48 100644 --- a/code/modules/antagonists/cult/cult_comms.dm +++ b/code/modules/antagonists/cult/cult_comms.dm @@ -83,7 +83,7 @@ if(choice == "Yes" && IsAvailable()) var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) if(!C.cult_team) - to_chat(owner, "Do you not alreaady lead yourself?") + to_chat(owner, "Do you not already lead yourself?") return pollCultists(owner,C.cult_team) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 16e1b45843..05c2596f65 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -105,8 +105,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/be_random_body = 0 //whether we'll have a random body every round var/gender = MALE //gender of character (well duh) var/age = 30 //age of character - var/language = "Random" //bonus language - var/choselanguage = "Random" //language appearance var/underwear = "Nude" //underwear type var/undie_color = "FFFFFF" var/undershirt = "Nude" //undershirt type @@ -130,6 +128,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/custom_speech_verb = "default" //if your say_mod is to be something other than your races var/custom_tongue = "default" //if your tongue is to be something other than your races + var/additional_language = "None" //additional language your character has var/modified_limbs = list() //prosthetic/amputated limbs var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded @@ -277,10 +276,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Character Settings" dat += "Character Appearance" - dat += "Loadout" + dat += "Character Speech" + dat += "Loadout" dat += "Game Preferences" - dat += "Content Preferences" - dat += "Keybindings" + dat += "Content Preferences" + dat += "Keybindings" if(!path) dat += "
Please create an account to save your preferences
" @@ -328,7 +328,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Gender: [gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
" dat += "Age: [age]
" - dat += "Language: [choselanguage]
" dat += "Special Names:
" var/old_group @@ -485,13 +484,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) else if(use_skintones || mutant_colors) dat += "" - dat += APPEARANCE_CATEGORY_COLUMN - dat += "

Speech preferences

" - dat += "Custom Speech Verb:
" - dat += "
[custom_speech_verb]
" - dat += "Custom Tongue:
" - dat += "
[custom_tongue]
" - if(HAIR in pref_species.species_traits) dat += APPEARANCE_CATEGORY_COLUMN @@ -678,6 +670,36 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "" dat += "" + if(3) + if(path) + var/savefile/S = new /savefile(path) + if(S) + dat += "
" + var/name + var/unspaced_slots = 0 + for(var/i=1, i<=max_save_slots, i++) + unspaced_slots++ + if(unspaced_slots > 4) + dat += "
" + unspaced_slots = 0 + S.cd = "/character[i]" + S["real_name"] >> name + if(!name) + name = "Character[i]" + dat += "[name] " + dat += "
" + + dat += "" + dat += "
" + dat += "

Speech preferences

" + dat += "Custom Speech Verb:
" + dat += "[custom_speech_verb]
" + dat += "Custom Tongue:
" + dat += "[custom_tongue]
" + dat += "Additional Language
" + dat += "[additional_language]
" + dat += "
" + if (1) // Game Preferences dat += "" dat += "
" dat += "

General Settings

" @@ -846,7 +868,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
" - if(3) + if(4) //calculate your gear points from the chosen item gear_points = CONFIG_GET(number/initial_gear_points) var/list/chosen_gear = loadout_data["SAVE_[loadout_slot]"] @@ -965,7 +987,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
[loadout_item ? (loadout_item[LOADOUT_CUSTOM_DESCRIPTION] ? loadout_item[LOADOUT_CUSTOM_DESCRIPTION] : gear.description) : gear.description] Progress: [min(progress_made, unlockable.progress_required)]/[unlockable.progress_required]
" - if(4) // Content preferences + if(5) // Content preferences dat += "
" dat += "

Fetish content prefs

" dat += "Arousal:[arousable == TRUE ? "Enabled" : "Disabled"]
" @@ -989,7 +1011,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Automatic Wagging: [(cit_toggles & NO_AUTO_WAG) ? "Disabled" : "Enabled"]
" dat += "
" dat += "
" - if(5) // Custom keybindings + if(6) // Custom keybindings dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Input"]
" dat += "Keybindings mode controls how the game behaves with tab and map/input focus.
If it is on Hotkeys, the game will always attempt to force you to map focus, meaning keypresses are sent \ directly to the map instead of the input. You will still be able to use the command bar, but you need to tab to do it every time you click on the game map.
\ @@ -2339,28 +2361,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) features["body_model"] = chosengender gender = chosengender - if("language") - choselanguage = input(user, "Select a language.", "Language", language) as null|anything in list("Beachtongue","Draconic","Dwarven", - "Chimpanzee","Space Sign Language","Random") - if(!choselanguage) - return - switch(choselanguage) - if("Rachidian") - language = /datum/language/arachnid - if("Beachtongue") - language = /datum/language/beachbum - if("Draconic") - language = /datum/language/draconic - if("Dwarven") - language = /datum/language/dwarf - if("Chimpanzee") - language = /datum/language/monkey - if("Space Sign Language") - language = /datum/language/signlanguage - if("Random") - language = pick(list("Rachidian", "Beachtongue","Draconic","Dwarven", - "Chimpanzee","Space Sign Language")) - if("body_size") var/new_body_size = input(user, "Choose your desired sprite size: (90-125%)\nWarning: This may make your character look distorted. Additionally, any size under 100% takes a 10% maximum health penalty", "Character Preference", features["body_size"]*100) as num|null if(new_body_size) @@ -2370,11 +2370,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/selected_custom_tongue = input(user, "Choose your desired tongue (none means your species tongue)", "Character Preference") as null|anything in GLOB.roundstart_tongues if(selected_custom_tongue) custom_tongue = selected_custom_tongue + if("speech_verb") var/selected_custom_speech_verb = input(user, "Choose your desired speech verb (none means your species speech verb)", "Character Preference") as null|anything in GLOB.speech_verbs if(selected_custom_speech_verb) custom_speech_verb = selected_custom_speech_verb + if("language") + var/selected_language = input(user, "Choose your desired additional language", "Character Preference") as null|anything in GLOB.roundstart_languages + if(selected_language) + additional_language = selected_language + if("bodysprite") var/selected_body_sprite = input(user, "Choose your desired body sprite", "Character Preference") as null|anything in pref_species.allowed_limb_ids if(selected_body_sprite) @@ -2909,6 +2915,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) new_custom_tongue.Insert(character) if(custom_speech_verb != "default") character.dna.species.say_mod = custom_speech_verb + if(additional_language && additional_language != "None") + var/language_entry = GLOB.roundstart_languages[additional_language] + if(language_entry) + character.grant_language(language_entry, TRUE, TRUE) //limb stuff, only done when initially spawning in if(initial_spawn) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 141346acde..812e8c4821 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -604,8 +604,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["body_model"] >> features["body_model"] S["body_size"] >> features["body_size"] S["age"] >> age - S["language"] >> language - S["choselanguage"] >> choselanguage S["hair_color"] >> hair_color S["facial_hair_color"] >> facial_hair_color S["eye_type"] >> eye_type @@ -626,6 +624,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["uplink_loc"] >> uplink_spawn_loc S["custom_speech_verb"] >> custom_speech_verb S["custom_tongue"] >> custom_tongue + S["additional_language"] >> additional_language S["feature_mcolor"] >> features["mcolor"] S["feature_lizard_tail"] >> features["tail_lizard"] S["feature_lizard_snout"] >> features["snout"] @@ -881,6 +880,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default") custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default") + additional_language = sanitize_inlist(additional_language, GLOB.roundstart_languages, "None") security_records = copytext(security_records, 1, MAX_FLAVOR_LEN) medical_records = copytext(medical_records, 1, MAX_FLAVOR_LEN) @@ -964,8 +964,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["body_model"] , features["body_model"]) WRITE_FILE(S["body_size"] , features["body_size"]) WRITE_FILE(S["age"] , age) - WRITE_FILE(S["language"] , language) - WRITE_FILE(S["choselanguage"] , choselanguage) WRITE_FILE(S["hair_color"] , hair_color) WRITE_FILE(S["facial_hair_color"] , facial_hair_color) WRITE_FILE(S["eye_type"] , eye_type) @@ -987,6 +985,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["species"] , pref_species.id) WRITE_FILE(S["custom_speech_verb"] , custom_speech_verb) WRITE_FILE(S["custom_tongue"] , custom_tongue) + WRITE_FILE(S["additional_language"] , additional_language) // records WRITE_FILE(S["security_records"] , security_records) diff --git a/code/modules/language/arachnid.dm b/code/modules/language/arachnid.dm index 92ea47781e..d021e5a35b 100644 --- a/code/modules/language/arachnid.dm +++ b/code/modules/language/arachnid.dm @@ -9,6 +9,7 @@ flags = NO_STUTTER | LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD icon_state = "arachnid" + chooseable_roundstart = TRUE /datum/language/arachnid/scramble(input) . = prob(65) ? "wiff" : "thump" diff --git a/code/modules/language/draconic.dm b/code/modules/language/draconic.dm index aaa998c2c0..ed72252773 100644 --- a/code/modules/language/draconic.dm +++ b/code/modules/language/draconic.dm @@ -18,3 +18,4 @@ ) icon_state = "lizard" default_priority = 90 + chooseable_roundstart = TRUE diff --git a/code/modules/language/dwarven.dm b/code/modules/language/dwarven.dm index 17a4674415..aded22cd6f 100644 --- a/code/modules/language/dwarven.dm +++ b/code/modules/language/dwarven.dm @@ -11,3 +11,4 @@ default_priority = 90 icon_state = "dwarf" + chooseable_roundstart = TRUE diff --git a/code/modules/language/language.dm b/code/modules/language/language.dm index 42b439ba03..f65d928301 100644 --- a/code/modules/language/language.dm +++ b/code/modules/language/language.dm @@ -22,6 +22,8 @@ var/list/scramble_cache = list() var/default_priority = 0 // the language that an atom knows with the highest "default_priority" is selected by default. + var/chooseable_roundstart = FALSE // can we pick it from the customization menu as an additional language? + // if you are seeing someone speak popcorn language, then something is wrong. var/icon = 'icons/misc/language.dmi' var/icon_state = "popcorn" diff --git a/code/modules/language/monkey.dm b/code/modules/language/monkey.dm index 53e598b02b..6f3da838bc 100644 --- a/code/modules/language/monkey.dm +++ b/code/modules/language/monkey.dm @@ -10,3 +10,4 @@ default_priority = 80 icon_state = "animal" + chooseable_roundstart = TRUE diff --git a/code/modules/language/mushroom.dm b/code/modules/language/mushroom.dm index b896d11449..038ee0f905 100644 --- a/code/modules/language/mushroom.dm +++ b/code/modules/language/mushroom.dm @@ -9,3 +9,4 @@ sentence_chance = 0 default_priority = 80 syllables = list("poof", "pff", "pFfF", "piff", "puff", "pooof", "pfffff", "piffpiff", "puffpuff", "poofpoof", "pifpafpofpuf") + chooseable_roundstart = TRUE diff --git a/code/modules/language/slime.dm b/code/modules/language/slime.dm index cca56ca933..6b7b1c366d 100644 --- a/code/modules/language/slime.dm +++ b/code/modules/language/slime.dm @@ -10,3 +10,4 @@ default_priority = 70 icon_state = "slime" + chooseable_roundstart = TRUE diff --git a/code/modules/language/sylvan.dm b/code/modules/language/sylvan.dm index 3bbf5f6afd..a1ac6725b9 100644 --- a/code/modules/language/sylvan.dm +++ b/code/modules/language/sylvan.dm @@ -16,3 +16,4 @@ ) icon_state = "plant" default_priority = 90 + chooseable_roundstart = TRUE diff --git a/code/modules/language/voltaic.dm b/code/modules/language/voltaic.dm index ead7fe7c7f..9a64f56889 100644 --- a/code/modules/language/voltaic.dm +++ b/code/modules/language/voltaic.dm @@ -12,3 +12,4 @@ ) icon_state = "volt" default_priority = 90 + chooseable_roundstart = TRUE diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 6af1c2118c..5e02d7ba47 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -928,7 +928,10 @@ ghost.ManualFollow(src) /obj/item/melee/ghost_sword/process() - ghost_check() + force = 0 + var/ghost_counter = ghost_check() + + force = clamp((ghost_counter * 4), 0, 75) /obj/item/melee/ghost_sword/proc/recursive_orbit_collect(atom/A, list/L) for(var/i in A.orbiters?.orbiters) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index f143f6302d..6f5109c90b 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1237,7 +1237,7 @@ if(user.incapacitated() || !user.Adjacent(src)) return FALSE if(W && user.a_intent == INTENT_HELP && W.can_give()) - user.give() + user.give(src) return TRUE /mob/living/carbon/verb/give_verb() @@ -1253,4 +1253,4 @@ var/obj/item/I = usr.get_active_held_item() var/mob/living/carbon/C = usr if(I.can_give()) - C.give() + C.give(src) 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 75aff774ce..fba6ecd40c 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -625,7 +625,7 @@ say_mod = "clicks" limbs_id = "clockgolem" info_text = "As a Clockwork Golem, you are faster than other types of golems, and are capable of using guns. On death, you will break down into scrap." - species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL) + species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL,ROBOTIC_LIMBS) inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER) inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID @@ -667,6 +667,10 @@ /datum/species/golem/clockwork/no_scrap //These golems are created through the herald's beacon and leave normal corpses on death. id = "clockwork golem servant" + species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOSTOMACH,NOLIVER,NOGENITALS,NOAROUSAL,NOTRANSSTING,ROBOTIC_LIMBS,HAS_BONE) + inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID + inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_NOHUNGER,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER) + inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID armor = 15 //Balance reasons make this armor weak no_equip = list() nojumpsuit = FALSE @@ -675,6 +679,8 @@ dangerous_existence = TRUE random_eligible = FALSE info_text = "As a Clockwork Golem Servant, you are faster than other types of golems, and are capable of using guns." //warcult golems leave a corpse + gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless) + /datum/species/golem/cloth name = "Cloth Golem" diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 8e39dc5234..486a0acf4e 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -514,10 +514,21 @@ /mob/living/ratvar_act() if(status_flags & GODMODE) return - if(stat != DEAD && !is_servant_of_ratvar(src)) + if(stat == DEAD || is_servant_of_ratvar(src)) + return + if(is_eligible_servant(src)) + add_servant_of_ratvar(src) + to_chat(src, "Ratvar's influence invades your mind, praise the Justiciar!") + else to_chat(src, "A blinding light boils you alive! Run!") adjust_fire_stacks(20) + adjustFireLoss(35) IgniteMob() + if(iscultist(src)) + to_chat(src, "You resist Ratvar's influence... but not all of it! Run!") + adjustFireLoss(35) + if(src && reagents) + reagents.add_reagent(/datum/reagent/fuel/holyoil, 5) return FALSE diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 5b5292a020..0ebbce53cf 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -80,6 +80,9 @@ SSshuttle.lockdown = TRUE SSpersistence.station_was_destroyed = TRUE sleep(600) + if(QDELETED(src)) + priority_announce("Accausal event alert rescinded. Eldritch presence no longer reading on sensors. Solution package disarmed. Reccomend immediate evacuation","Central Command Higher Dimensional Affairs") + return if(resolved == FALSE) resolved = TRUE sound_to_playing_players('sound/machines/alarm.ogg') diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 471b2f931e..e45434cec4 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -94,7 +94,7 @@ /datum/design/medicinalsmartdart name = "Medicinal Smartdart" - desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented." + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using its smart nanofilter technology, only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented." id = "medicinalsmartdart" build_type = PROTOLATHE materials = list(/datum/material/glass = 100, /datum/material/plastic = 100, /datum/material/iron = 100) @@ -192,6 +192,16 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE +/datum/design/hypospraykit + name = "Empty Hypospray Kit" + desc = "A plastic medical kit for storing hyposprays and hypospray accessories." + id = "hypokit" + build_type = PROTOLATHE + materials = list(/datum/material/plastic = 5000) + build_path = /obj/item/storage/hypospraykit // let's not summon new hyposprays thanks + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + /datum/design/blood_bag name = "Empty Blood Bag" desc = "A small sterilized plastic bag for blood." @@ -203,7 +213,7 @@ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/bsblood_bag - name = "Blue Space Empty Blood Bag" + name = "Empty Bluespace Blood Bag" desc = "A large sterilized plastic bag for blood." id = "bsblood_bag" build_path = /obj/item/reagent_containers/blood/bluespace diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 40cc322eed..c7c2e7ef10 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -104,5 +104,6 @@ // Default research tech, prevents bricking design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", "desttagger", "handlabel", "packagewrap", "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "bepis", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "paystand", - "space_heater", "beaker", "large_beaker", "bucket", "xlarge_beaker", "sec_shellclip", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_islug", "sec_dart", "sec_38", "sec_38lethal", + "space_heater", "beaker", "large_beaker", "xlarge_beaker", "bucket", "hypovial", "large_hypovial", + "sec_shellclip", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_islug", "sec_dart", "sec_38", "sec_38lethal", "rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass") diff --git a/code/modules/research/techweb/nodes/biotech_nodes.dm b/code/modules/research/techweb/nodes/biotech_nodes.dm index 3c89f0bbab..d4f0a4b913 100644 --- a/code/modules/research/techweb/nodes/biotech_nodes.dm +++ b/code/modules/research/techweb/nodes/biotech_nodes.dm @@ -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", "portable_chem_mixer") + design_ids = list("medicalkit", "hypokit", "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 diff --git a/code/modules/research/techweb/nodes/bluespace_nodes.dm b/code/modules/research/techweb/nodes/bluespace_nodes.dm index ae9fdd6485..459a4d6616 100644 --- a/code/modules/research/techweb/nodes/bluespace_nodes.dm +++ b/code/modules/research/techweb/nodes/bluespace_nodes.dm @@ -24,6 +24,14 @@ design_ids = list("bluespace_matter_bin", "femto_mani", "triphasic_scanning", "bluespace_crystal", "xenobio_slimeadv") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) +/datum/techweb_node/emp_super + id = "emp_super" + display_name = "Quantum Electromagnetic Technology" + description = "Even better electromagnetic technology." + prereq_ids = list("emp_adv", "adv_bluespace") // why should the rest of T4 be locked but not this node? grmblgrmbl + design_ids = list("quadultra_micro_laser") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) + /datum/techweb_node/bluespace_power id = "bluespace_power" display_name = "Bluespace Power Technology" @@ -37,7 +45,7 @@ display_name = "Bluespace Pockets" description = "Studies into the mysterious alternate dimension known as bluespace and how to place items in the threads of reality." prereq_ids = list("adv_power", "adv_bluespace", "adv_biotech", "adv_plasma") - design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding", "bsblood_bag", "duffelbag_holding") + design_ids = list("bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding", "bsblood_bag", "duffelbag_holding") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5500) /datum/techweb_node/bluespace_portal diff --git a/code/modules/research/techweb/nodes/misc_nodes.dm b/code/modules/research/techweb/nodes/misc_nodes.dm index 94a19924b8..2e5fdca6bf 100644 --- a/code/modules/research/techweb/nodes/misc_nodes.dm +++ b/code/modules/research/techweb/nodes/misc_nodes.dm @@ -49,14 +49,6 @@ design_ids = list("ultra_micro_laser") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) -/datum/techweb_node/emp_super - id = "emp_super" - display_name = "Quantum Electromagnetic Technology" //bs - description = "Even better electromagnetic technology." - prereq_ids = list("emp_adv") - design_ids = list("quadultra_micro_laser") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) - /////////////////////////Clown tech///////////////////////// /datum/techweb_node/clown id = "clown" diff --git a/html/changelog.html b/html/changelog.html index 3fb5e9cdfe..0e8693f4cb 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,29 @@ -->
+

18 March 2021

+

Arturlang updated:

+
    +
  • Combat mode right click and right click verb give's are now actualyl targeted
  • +
+

Hatterhat updated:

+
    +
  • Hypospray vials are now printable from the medical techshift start.
  • +
  • Empty hypospray kits are now printable behind biological technology. tweak: Quantum electromag (T4 lasers) are now behind Advanced Bluespace like the rest of T4.
  • +
+ +

17 March 2021

+

KeRSedChaplain updated:

+
    +
  • Added three new rites, and makes soul vessels obtainable
  • +
  • fixes clockwork guardians inheriting marauders blocking
  • +
  • added sounds for the ratvar end sequence, voiced by @dzahlus
  • +
+

timothyteakettle updated:

+
    +
  • speech panel added to main menu customization
  • +
+

16 March 2021

GrayRachnid updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 077ad2aedb..cd9d07e740 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -28737,3 +28737,18 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - balance: Made nitryl's cargo sell value less (10 instead of 30) SandPoot: - bugfix: Fixed interacting with telecomms. +2021-03-17: + KeRSedChaplain: + - rscadd: Added three new rites, and makes soul vessels obtainable + - bugfix: fixes clockwork guardians inheriting marauders blocking + - soundadd: added sounds for the ratvar end sequence, voiced by @dzahlus + timothyteakettle: + - rscadd: speech panel added to main menu customization +2021-03-18: + Arturlang: + - bugfix: Combat mode right click and right click verb give's are now actualyl targeted + Hatterhat: + - rscadd: Hypospray vials are now printable from the medical techshift start. + - rscadd: 'Empty hypospray kits are now printable behind biological technology. + tweak: Quantum electromag (T4 lasers) are now behind Advanced Bluespace like + the rest of T4.' diff --git a/icons/mob/actions/actions_clockcult.dmi b/icons/mob/actions/actions_clockcult.dmi index 92d6f98e73..d4f5c4ed6f 100644 Binary files a/icons/mob/actions/actions_clockcult.dmi and b/icons/mob/actions/actions_clockcult.dmi differ diff --git a/icons/mob/clockwork_mobs.dmi b/icons/mob/clockwork_mobs.dmi index 54690f6cac..b43f7f958e 100644 Binary files a/icons/mob/clockwork_mobs.dmi and b/icons/mob/clockwork_mobs.dmi differ diff --git a/icons/mob/inhands/antag/clockwork_righthand.dmi b/icons/mob/inhands/antag/clockwork_righthand.dmi index 64ee6199a7..c813c83634 100644 Binary files a/icons/mob/inhands/antag/clockwork_righthand.dmi and b/icons/mob/inhands/antag/clockwork_righthand.dmi differ diff --git a/sound/magic/clockwork/ratvar_announce.ogg b/sound/magic/clockwork/ratvar_announce.ogg new file mode 100644 index 0000000000..6f997108c9 Binary files /dev/null and b/sound/magic/clockwork/ratvar_announce.ogg differ diff --git a/sound/magic/clockwork/ratvar_announce1.ogg b/sound/magic/clockwork/ratvar_announce1.ogg new file mode 100644 index 0000000000..08308cb1cd Binary files /dev/null and b/sound/magic/clockwork/ratvar_announce1.ogg differ diff --git a/sound/magic/clockwork/ratvar_announce2.ogg b/sound/magic/clockwork/ratvar_announce2.ogg new file mode 100644 index 0000000000..54a49c75c7 Binary files /dev/null and b/sound/magic/clockwork/ratvar_announce2.ogg differ diff --git a/sound/magic/clockwork/ratvarfire.ogg b/sound/magic/clockwork/ratvarfire.ogg new file mode 100644 index 0000000000..4b8a9be10a Binary files /dev/null and b/sound/magic/clockwork/ratvarfire.ogg differ diff --git a/sound/weapons/neovgre_laser.ogg b/sound/weapons/neovgre_laser.ogg index da97117ae8..c36e54fe87 100644 Binary files a/sound/weapons/neovgre_laser.ogg and b/sound/weapons/neovgre_laser.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 7879a87e32..b15633366e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1617,6 +1617,7 @@ #include "code\modules\antagonists\clockcult\clock_items\clock_weapons\ratvarian_shield.dm" #include "code\modules\antagonists\clockcult\clock_items\clock_weapons\ratvarian_spear.dm" #include "code\modules\antagonists\clockcult\clock_mobs\_eminence.dm" +#include "code\modules\antagonists\clockcult\clock_mobs\clockwork_guardian.dm" #include "code\modules\antagonists\clockcult\clock_mobs\clockwork_marauder.dm" #include "code\modules\antagonists\clockcult\clock_scriptures\scripture_applications.dm" #include "code\modules\antagonists\clockcult\clock_scriptures\scripture_cyborg.dm"