diff --git a/Build.bat b/Build.bat index dd3a6fd9d9..bac5e94350 100644 --- a/Build.bat +++ b/Build.bat @@ -1,2 +1,2 @@ @call tools\build\build -@pause +rem @pause do not pause me you piece of crap 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/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm index 8f01f453b6..b5d322a091 100644 --- a/code/__DEFINES/reactions.dm +++ b/code/__DEFINES/reactions.dm @@ -21,10 +21,10 @@ #define STIMULUM_FIRST_DROP 0.065 #define STIMULUM_SECOND_RISE 0.0009 #define STIMULUM_ABSOLUTE_DROP 0.00000335 -#define REACTION_OPPRESSION_THRESHOLD 5 +#define REACTION_OPPRESSION_THRESHOLD 10 #define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense. //Research point amounts -#define NOBLIUM_RESEARCH_AMOUNT 1000 +#define NOBLIUM_RESEARCH_AMOUNT 25 #define BZ_RESEARCH_SCALE 4 #define BZ_RESEARCH_MAX_AMOUNT 400 #define MIASMA_RESEARCH_AMOUNT 6 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 10ea9cc3f0..23fd75f982 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -219,20 +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) -*/ //kills this awful excuse of a thing, quirk point requirement is a no-no 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/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index 2943130a19..9202fd1f81 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -171,11 +171,11 @@ var/worth = 10 worth += C.air_contents.get_moles(/datum/gas/bz)*3 worth += C.air_contents.get_moles(/datum/gas/stimulum)*25 - worth += C.air_contents.get_moles(/datum/gas/hypernoblium)*1000 + worth += C.air_contents.get_moles(/datum/gas/hypernoblium)*20 worth += C.air_contents.get_moles(/datum/gas/miasma)*2 worth += C.air_contents.get_moles(/datum/gas/tritium)*7 worth += C.air_contents.get_moles(/datum/gas/pluoxium)*6 - worth += C.air_contents.get_moles(/datum/gas/nitryl)*30 + worth += C.air_contents.get_moles(/datum/gas/nitryl)*10 return worth diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 9b182e1b8b..ce7b792f75 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -113,7 +113,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/vorepref = "Ask" var/extremepref = "No" //This is for extreme shit, maybe even literal shit, better to keep it on no by default var/extremeharm = "No" //If "extreme content" is enabled, this option serves as a toggle for the related interactions to cause damage or not - var/list/language = list() var/see_chat_emotes = TRUE var/enable_personal_chat_color = FALSE var/personal_chat_color = "#ffffff" @@ -141,6 +140,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/list/language = list() //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 @@ -288,10 +288,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
" @@ -352,11 +353,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "[namedata["pref_name"]]: [custom_names[custom_name_id]] " dat += "

" - //SKYRAT EDIT - additional language - dat += "Additional Language
" - var/list/languages_sorted = sortList(language) - dat += "[language.len ? languages_sorted.Join(", ") : "None"]
" - // dat += "Custom job preferences:
" dat += "Preferred AI Core Display: [preferred_ai_core_display]
" dat += "Preferred Security Department: [prefered_security_department]
" @@ -510,16 +506,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "

Right Eye Color

" dat += "    #[right_eye_color]
" - dat += "

Speech preferences

" - dat += "Custom Speech Verb:
" - dat += "
[custom_speech_verb]
" - dat += "Custom Tongue:
" - dat += "
[custom_tongue]
" - //SKYRAT EDIT - dat += "Custom runechat color: [enable_personal_chat_color ? "Enabled" : "Disabled"]
[enable_personal_chat_color ? "    [personal_chat_color]" : ""]
" - dat += "" - //END OF SKYRAT EDIT - if(HAIR in pref_species.species_traits) dat += APPEARANCE_CATEGORY_COLUMN @@ -708,6 +694,41 @@ 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 += "" + //END OF SKYRAT EDIT + dat += "" + dat += "
" + dat += "

Speech preferences

" + dat += "Custom Speech Verb:
" + dat += "[custom_speech_verb]
" + dat += "Custom Tongue:
" + dat += "[custom_tongue]
" + //SKYRAT EDIT - additional language + runechat color + dat += "Additional Language
" + var/list/languages_sorted = sortList(language) + dat += "[language.len ? languages_sorted.Join(", ") : "None"]
" + dat += "Custom runechat color: [enable_personal_chat_color ? "Enabled" : "Disabled"]
[enable_personal_chat_color ? "    [personal_chat_color]" : ""]
" + dat += "
" + if (1) // Game Preferences 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]"] @@ -1003,7 +1024,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "" dat += "
" dat += "

General Settings

" @@ -884,7 +905,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 += "Allow Lewd Verbs: [(toggles & VERB_CONSENT) ? "Yes":"No"]
" // Skyrat - ERP Mechanic Addition @@ -1034,7 +1055,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.
\ diff --git a/code/modules/language/arachnid.dm b/code/modules/language/arachnid.dm index 95232155a4..e68e7a181b 100644 --- a/code/modules/language/arachnid.dm +++ b/code/modules/language/arachnid.dm @@ -10,7 +10,7 @@ icon_state = "arachnid" //SKYRAT CHANGE - language restriction - restricted = TRUE + restricted = FALSE // /datum/language/arachnid/scramble(input) diff --git a/code/modules/language/draconic.dm b/code/modules/language/draconic.dm index fe7ed28fc9..288831e1cd 100644 --- a/code/modules/language/draconic.dm +++ b/code/modules/language/draconic.dm @@ -19,5 +19,5 @@ icon_state = "lizard" default_priority = 90 //SKYRAT CHANGE - language restriction - restricted = TRUE + restricted = FALSE // diff --git a/code/modules/language/dwarven.dm b/code/modules/language/dwarven.dm index ffd22dd3f8..fa8f81244b 100644 --- a/code/modules/language/dwarven.dm +++ b/code/modules/language/dwarven.dm @@ -6,11 +6,11 @@ space_chance = 100 // Each 'syllable' is its own word key = "D" flags = TONGUELESS_SPEECH - //SKYRAT CHANGE - language restriction - restricted = FALSE - // syllables = list("kulet", "alak", "bidok", "nicol", "anam", "gatal", "mabdug", "zustash", "sedil", "ustos", "emr", "izeg", "beming", "gost", "ntak", "tosid", "feb", "berim", "ibruk", "ermis", "thoth", "thatthil", "gistang", "libash", "lakish", "asdos", "roder", "nel", "biban", "ugog", "ish", "robek", "olmul", "nokzam", "emuth", "fer", "uvel", "dolush", "ag^k", "ucat", "ng rak", "enir", "ugath", "lisig", "etg", "erong", "osed", "lanlar", "udir", "tarmid", "s krith", "nural", "bugsud", "okag", "nazush", "nashon", "ftrid", "en''r", "dstik", "kogan", "ingish", "dudgoth", "stalk*b", "themor", "murak", "altth", "osod", "thcekut", "cog", "selsten", "egdoth", "othsin", "idek", "st", "suthmam", "im", "okab", "onlnl", "gasol", "tegir", "nam...sh", "noval", "shalig", "shin", "lek", ",,kim", "kfkdal", "stum,,m", "alud", "olom", "%lot", "rozsed", "thos", "okon", "nRatvar'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/html/changelog.html b/html/changelog.html index ebd0140ecc..b9bee52d4b 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,33 @@ -->
+

16 March 2021

+

GrayRachnid updated:

+
    +
  • removed red toolbox, agent id, and guerilla gloves from unlocking illegal tech.
  • +
+

HeroWithYay updated:

+
    +
  • fixed spelling error
  • +
+

LetterN updated:

+
    +
  • Borg light icons not turning off
  • +
  • Double ai icon select + Fixes ai core not having icons
  • +
  • Missing air tank icon
  • +
  • Computer boards being dumb and nullspacing/qdeling itself
  • +
+

Putnam3145 updated:

+
    +
  • Supernova now much lower chance to be inconsequential
  • +
  • Made hyper-nob's point values way lower (25/20 for science/cargo instead of 1000/1000)
  • +
  • Made nitryl's cargo sell value less (10 instead of 30)
  • +
+

SandPoot updated:

+
    +
  • Fixed interacting with telecomms.
  • +
+

14 March 2021

Adelphon updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index beaded111a..f6aac42286 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -29282,3 +29282,21 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - rscadd: adds a cute new plushie necromanceranne: - bugfix: Fixes cosmetic augments missing their foot sprites. +2021-03-16: + GrayRachnid: + - balance: removed red toolbox, agent id, and guerilla gloves from unlocking illegal + tech. + HeroWithYay: + - bugfix: fixed spelling error + LetterN: + - bugfix: Borg light icons not turning off + - bugfix: Double ai icon select + Fixes ai core not having icons + - bugfix: Missing air tank icon + - bugfix: Computer boards being dumb and nullspacing/qdeling itself + Putnam3145: + - balance: Supernova now much lower chance to be inconsequential + - balance: Made hyper-nob's point values way lower (25/20 for science/cargo instead + of 1000/1000) + - balance: Made nitryl's cargo sell value less (10 instead of 30) + SandPoot: + - bugfix: Fixed interacting with telecomms. diff --git a/html/changelogs/AutoChangeLog-pr-14141.yml b/html/changelogs/AutoChangeLog-pr-14141.yml new file mode 100644 index 0000000000..1279051bb8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14141.yml @@ -0,0 +1,6 @@ +author: "KeRSedChaplain" +delete-after: True +changes: + - 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" diff --git a/html/changelogs/AutoChangeLog-pr-14347.yml b/html/changelogs/AutoChangeLog-pr-14347.yml new file mode 100644 index 0000000000..b9ec2d6bd4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14347.yml @@ -0,0 +1,4 @@ +author: "timothyteakettle" +delete-after: True +changes: + - rscadd: "speech panel added to main menu customization" diff --git a/html/changelogs/AutoChangeLog-pr-14397.yml b/html/changelogs/AutoChangeLog-pr-14397.yml deleted file mode 100644 index ba93472587..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14397.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SandPoot" -delete-after: True -changes: - - bugfix: "Fixed interacting with telecomms." diff --git a/html/changelogs/AutoChangeLog-pr-14398.yml b/html/changelogs/AutoChangeLog-pr-14398.yml deleted file mode 100644 index ff5999c8d4..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14398.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "LetterN" -delete-after: True -changes: - - bugfix: "Borg light icons not turning off" - - bugfix: "Double ai icon select + Fixes ai core not having icons" - - bugfix: "Missing air tank icon" - - bugfix: "Computer boards being dumb and nullspacing/qdeling itself" diff --git a/html/changelogs/AutoChangeLog-pr-14421.yml b/html/changelogs/AutoChangeLog-pr-14421.yml deleted file mode 100644 index f86bb440bf..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14421.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "GrayRachnid" -delete-after: True -changes: - - balance: "removed red toolbox, agent id, and guerilla gloves from unlocking illegal tech." diff --git a/html/changelogs/AutoChangeLog-pr-14433.yml b/html/changelogs/AutoChangeLog-pr-14433.yml deleted file mode 100644 index a74cf85bc9..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14433.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "HeroWithYay" -delete-after: True -changes: - - bugfix: "fixed spelling error" diff --git a/html/changelogs/AutoChangeLog-pr-14437.yml b/html/changelogs/AutoChangeLog-pr-14437.yml deleted file mode 100644 index 1e2dbadbfe..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14437.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - balance: "Supernova now much lower chance to be inconsequential" 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/clothing/custom_w.dmi b/icons/mob/clothing/custom_w.dmi index 3d3e0d24aa..1a4acbc242 100644 Binary files a/icons/mob/clothing/custom_w.dmi and b/icons/mob/clothing/custom_w.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/icons/obj/custom.dmi b/icons/obj/custom.dmi index a361d2bf6e..7b00d52f8f 100644 Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index cdbd49050a..dd13f73f57 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -549,3 +549,8 @@ path = /obj/item/clothing/mask/breath/mmask ckeywhitelist = list("sneka") +/datum/gear/donator/smaiden + name = "Shrine Maiden" + slot = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/smaiden + ckeywhitelist = list("ultimarifox") diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index 3a3ecccc34..89734106cf 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -601,3 +601,12 @@ item_state = "mmask" mob_overlay_icon = 'icons/mob/clothing/custom_w.dmi' icon_state = "mmask" + +/obj/item/clothing/suit/smaiden + name = "shrine maiden" + desc = "Seems questionably tight for religious purposes." + icon_state = "smaiden" + item_state = "smaiden" + icon = 'icons/obj/custom.dmi' + mob_overlay_icon = 'icons/mob/clothing/custom_w.dmi' + mutantrace_variation = NONE diff --git a/modular_sand/code/modules/language/language.dm b/modular_sand/code/modules/language/language.dm index 9f9b13ec02..3ccb984ce5 100644 --- a/modular_sand/code/modules/language/language.dm +++ b/modular_sand/code/modules/language/language.dm @@ -32,7 +32,7 @@ ) icon_state = "buggy" default_priority = 94 - restricted = TRUE + restricted = FALSE /datum/language/modular_sand/calcic name = "Calcic" @@ -53,7 +53,7 @@ ) icon_state = "calcic" default_priority = 89 - restricted = TRUE + restricted = FALSE /datum/language/modular_sand/dunmeri name = "Dunmeri" @@ -96,7 +96,7 @@ ) icon_state = "moffic" default_priority = 93 - restricted = TRUE + restricted = FALSE /datum/language/modular_sand/neokanji name = "Neo-Kanji" 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 ef4c4eec6f..c9bf3b3981 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1620,6 +1620,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"