diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index af7671a10d6..7a6e820a2f6 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -56,7 +56,7 @@ /obj/attacked_by(obj/item/I, mob/living/user) if(I.force) - visible_message("[user] has hit [src] with [I]!", null, null, COMBAT_MESSAGE_RANGE, user) + visible_message("[user] has hit [src] with [I]!", null, null, COMBAT_MESSAGE_RANGE) //only witnesses close by and the victim see a hit message. take_damage(I.force, I.damtype, "melee", 1) @@ -105,6 +105,6 @@ if(user in viewers(src, null)) attack_message = "[user] has [message_verb] [src][message_hit_area] with [I]!" visible_message("[attack_message]", \ - "[attack_message]", null, COMBAT_MESSAGE_RANGE,user) + "[attack_message]", null, COMBAT_MESSAGE_RANGE) return 1 diff --git a/code/datums/martial.dm b/code/datums/martial.dm index eb68ce0e064..dca344b774e 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -47,7 +47,7 @@ if(!damage) playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1) D.visible_message("[A] has attempted to [atk_verb] [D]!", \ - "[A] has attempted to [atk_verb] [D]!", null, COMBAT_MESSAGE_RANGE, A) + "[A] has attempted to [atk_verb] [D]!", null, COMBAT_MESSAGE_RANGE) add_logs(A, D, "attempted to [atk_verb]") return 0 @@ -56,7 +56,7 @@ playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) D.visible_message("[A] has [atk_verb]ed [D]!", \ - "[A] has [atk_verb]ed [D]!", null, COMBAT_MESSAGE_RANGE, A) + "[A] has [atk_verb]ed [D]!", null, COMBAT_MESSAGE_RANGE) D.apply_damage(damage, BRUTE, affecting, armor_block) @@ -108,7 +108,7 @@ if(!damage) playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1) D.visible_message("[A] has attempted to [atk_verb] [D]!", \ - "[A] has attempted to [atk_verb] [D]!", null, COMBAT_MESSAGE_RANGE, A) + "[A] has attempted to [atk_verb] [D]!", null, COMBAT_MESSAGE_RANGE) add_logs(A, D, "attempted to hit", atk_verb) return 0 @@ -119,7 +119,7 @@ playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) D.visible_message("[A] has [atk_verb]ed [D]!", \ - "[A] has [atk_verb]ed [D]!", null, COMBAT_MESSAGE_RANGE, A) + "[A] has [atk_verb]ed [D]!", null, COMBAT_MESSAGE_RANGE) D.apply_damage(damage, STAMINA, affecting, armor_block) add_logs(A, D, "punched (boxing) ") diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm index 96826ec878a..a1a0b550f22 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm @@ -11,6 +11,8 @@ var/no_cost = FALSE //If the slab is admin-only and needs no components and has no scripture locks var/nonhuman_usable = FALSE //if the slab can be used by nonhumans, defaults to off var/produces_components = TRUE //if it produces components at all + var/list/shown_scripture = list(SCRIPTURE_DRIVER = FALSE, SCRIPTURE_SCRIPT = FALSE, SCRIPTURE_APPLICATION = FALSE, SCRIPTURE_REVENANT = FALSE, SCRIPTURE_JUDGEMENT = FALSE) + var/text_hidden = FALSE var/obj/effect/proc_holder/slab/slab_ability //the slab's current bound ability, for certain scripture actions_types = list(/datum/action/item_action/clock/hierophant, /datum/action/item_action/clock/guvax, /datum/action/item_action/clock/vanguard) @@ -219,7 +221,8 @@ return recite_scripture(user) if("Recollection") - show_guide(user) + user.set_machine(src) + interact(user) if("Cancel") return return 1 @@ -261,7 +264,7 @@ return 1 //Guide to Serving Ratvar -/obj/item/clockwork/slab/proc/show_guide(mob/living/user) +/obj/item/clockwork/slab/interact(mob/living/user) var/text = "If you're seeing this, file a bug report." if(ratvar_awakens) text = "" @@ -269,54 +272,96 @@ text += "HONOR RATVAR " text += "" else - text = "
Chetr nyy hagehguf-naq-ubabe Ratvar.


\ + + text = "
Chetr nyy hagehguf-naq-ubabe Ratvar.

\ \ - First and foremost, you serve Ratvar, the Clockwork Justiciar, in any ways he sees fit. This is with no regard to your personal well-being, and you would do well to think of the larger \ - scale of things than your life. Through foul and unholy magics was the Celestial Derelict formed, and fouler still those which trapped your master within it for all eternity. The Justiciar \ - wishes retribution upon those who performed this terrible act upon him - the Nar-Sian cultists - and you are to help him obtain it.

\ - \ - This is not a trivial task. Due to the nature of his prison, Ratvar is incapable of directly influencing the mortal plane. There is, however, a workaround - links between the perceptible \ - universe and Reebe (the Celestial Derelict) can be created and utilized. This is typically done via the creation of a slab akin to the one you are holding right now. The slabs tap into the \ - tidal flow of energy and information keeping Reebe sealed and presents it as meaningless images to preserve sanity. This slab can utilize the power in many different ways.

\ - \ - This is done through Components - pieces of the Justiciar's body that have since fallen off in the countless years since his imprisonment. Ratvar's unfortunate condition results \ - in the fragmentation of his body. These components still house great power on their own, and can slowly be drawn from Reebe by links capable of doing so.
\ - The most basic of these links lies in the clockwork slab, which will slowly generate components over time - one component of a random type is produced every 1 minute and 30 seconds, plus 30 seconds per each servant above 5, \ - which is obviously inefficient. There are other, more efficient, ways to create these components through scripture and certain structures.

\ - \ - In addition to their ability to generate components, slabs also possess other functionalities...

\ - \ - The first functionality of the slab is Recital. This allows you to consume components either from your slab or from the global cache (more on that in the scripture list) to perform \ - effects usually considered magical in nature.
\ - Effects vary considerably, including mass conversion, construction of various structures, or causing a massive global hallucination. Nevertheless, scripture is extremely important to a successful takeover.

\ - \ - The second functionality of the clockwork slab is Recollection, which will display this guide.

\ - \ - The third to fifth functionalities are several buttons in the top left while holding the slab, from left to right, they are:
\ - Hierophant Network, which allows communication to other servants.
\ - Guvax, which simply allows you to quickly invoke the Guvax scripture.
\ - Vanguard, which, like Guvax, simply allows you to quickly invoke the Vanguard scripture.

\ - \ - Examine the slab for component amount information.

\ - \ - A complete list of scripture, its effects, and its requirements can be found below.
\ +
[text_hidden ? "Show":"Hide"] Information

" + if(!text_hidden) + var/servants = 0 + var/production_time = SLAB_PRODUCTION_TIME + for(var/mob/living/M in living_mob_list) + if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M))) + servants++ + if(servants > 5) + servants -= 5 + production_time += min(SLAB_SERVANT_SLOWDOWN * servants, SLAB_SLOWDOWN_MAXIMUM) + var/production_text_addon = "" + if(production_time != SLAB_PRODUCTION_TIME+SLAB_SLOWDOWN_MAXIMUM) + production_text_addon = ", which increases for each human or silicon servant above 5" + production_time = production_time/600 + var/production_text = "[round(production_time)] minute\s" + if(production_time != round(production_time)) + production_time -= round(production_time) + production_time *= 60 + production_text += " and [round(production_time, 1)] second\s" + production_text += "" + production_text += production_text_addon + + text += "First and foremost, you serve Ratvar, the Clockwork Justicar, in any ways he sees fit. This is with no regard to your personal well-being, and you would do well to think of the larger \ + scale of things than your life. Ratvar wishes retribution upon those that trapped him in Reebe - the Nar-Sian cultists - and you are to help him obtain it.

\ + \ + Ratvar, being trapped in Reebe, the Celestial Derelict, cannot directly affect the mortal plane. However, links, such as this Clockwork Slab, can be created to draw \ + Components, fragments of the Justicar, from Reebe, and those Components can be used to draw power and material from Reebe through arcane chants \ + known as Scripture.

\ + \ + One component of a random type is produced in this slab every [production_text].
\ + Components are stored either within slabs, where they can only be accessed by that slab, or in the Global Cache accessed by Tinkerer's Caches, which all slabs \ + can draw from to recite scripture.
\ + There are five types of component, and in general, Belligerent Eyes are aggressive and judgemental, Vanguard Cogwheels are defensive and \ + repairing, Guvax Capacitors are for conversion and control, Replicant Alloy is for construction and fuel, and \ + Hierophant Ansibles are for transmission and power, though in combination their effects become more nuanced.

\ + \ + There are also five tiers of Scripture; [SCRIPTURE_DRIVER], [SCRIPTURE_SCRIPT], [SCRIPTURE_APPLICATION], [SCRIPTURE_REVENANT], and [SCRIPTURE_JUDGEMENT].
\ + Each tier has additional requirements, including Servants, Tinkerer's Caches, and Construction Value(CV). Construction Value is gained by creating structures or converting the \ + station, and everything too large to hold will grant some amount of it.

\ + \ + This would be a massive amount of information to try and keep track of, but all Servants have the Global Records alert, which appears in the top right.
\ + Mousing over that alert will display Servants, Caches, CV, and other information, such as the tiers of scripture that are unlocked.

\ + \ + On that note, Scripture is recited through Recital, the first and most important function of the slab.
\ + All scripture requires some amount of Components to recite, and only the weakest scripture does not consume any components when recited.
\ + However, weak is relative when it comes to scripture; even the 'weakest' could be enough to dominate a station in the hands of cunning Servants, and higher tiers of scripture are even \ + stronger in the right hands.

\ + \ + Some effects of scripture include granting the invoker a temporary complete immunity to stuns, summoning a turret that can attack anything that sets eyes on it, binding a powerful guardian \ + to the invoker, or even, at one of the highest tiers, granting all nearby Servants temporary invulnerability.
\ + However, the most important scripture is Guvax, which allows you to convert heathens with relative ease.

\ + \ + The second function of the clockwork slab is Recollection, which will display this guide.

\ + \ + The third to fifth functions are three buttons in the top left while holding the slab.
From left to right, they are:
\ + Hierophant Network, which allows communication to other Servants.
\ + Guvax, which simply allows you to quickly invoke the Guvax Driver.
\ + Vanguard, which, like the Guvax button, simply allows you to quickly invoke the Vanguard Driver.

\ + \ + Examine the slab to check the number of components it has available.

\ + \ +
Hide Above Information

" + + text += "A complete list of scripture, its effects, and its requirements can be found below.
\ Key:
" for(var/i in clockwork_component_cache) text += "[get_component_acronym(i)] = [get_component_name(i)][i != REPLICANT_ALLOY ? "s":""]
" var/text_to_add = "" - var/drivers = "
[SCRIPTURE_DRIVER]
These scriptures are always unlocked.
" - var/scripts = "
[SCRIPTURE_SCRIPT]
These scriptures require at least five servants and a tinkerer's cache.
" - var/applications = "
[SCRIPTURE_APPLICATION]
These scriptures require at least eight servants, three tinkerer's caches, and 100CV.
" - var/revenant = "
[SCRIPTURE_REVENANT]
These scriptures require at least ten servants and 200CV.
" - var/judgement = "
[SCRIPTURE_JUDGEMENT]
These scriptures require at least twelve servants and 300CV. In addition, there may not be any active non-servant AIs.
" + var/drivers = "
[SCRIPTURE_DRIVER]
These scriptures are always unlocked.
" + var/scripts = "
[SCRIPTURE_SCRIPT]
These scriptures require at least 5 Servants and \ + 1 Tinkerer's Cache.
" + var/applications = "
[SCRIPTURE_APPLICATION]
These scriptures require at least 8 Servants, \ + 3 Tinkerer's Caches, and 100CV.
" + var/revenant = "
[SCRIPTURE_REVENANT]
These scriptures require at least 10 Servants, \ + 4 Tinkerer's Caches, and 200CV.
" + var/judgement = "
[SCRIPTURE_JUDGEMENT]
This scripture requires at least 12 Servants, \ + 5 Tinkerer's Caches, and 300CV.
In addition, there may not be any active non-Servant AIs.

" for(var/V in sortList(subtypesof(/datum/clockwork_scripture), /proc/cmp_clockscripture_priority)) var/datum/clockwork_scripture/S = V - if(initial(S.tier) != SCRIPTURE_PERIPHERAL) + var/initial_tier = initial(S.tier) + if(initial_tier != SCRIPTURE_PERIPHERAL && shown_scripture[initial_tier]) var/datum/clockwork_scripture/S2 = new V var/list/req_comps = S2.required_components var/list/cons_comps = S2.consumed_components qdel(S2) - var/scripture_text = "
[initial(S.name)]:
[initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\ + var/scripture_text = "
[initial(S.name)]:
[initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] second\s
\ + [initial(S.invokers_required) > 1 ? "Invokers Required: [initial(S.invokers_required)]
":""]\ Component Requirement: " for(var/i in req_comps) if(req_comps[i]) @@ -329,7 +374,7 @@ scripture_text += "[cons_comps[i]] [get_component_acronym(i)] " break //we want this to only show up if the scripture has a cost of some sort scripture_text += "
Tip: [initial(S.usage_tip)]
" - switch(initial(S.tier)) + switch(initial_tier) if(SCRIPTURE_DRIVER) drivers += scripture_text if(SCRIPTURE_SCRIPT) @@ -347,3 +392,22 @@ popup.set_content(text) popup.open() return 1 + +/obj/item/clockwork/slab/Topic(href, href_list) + . = ..() + if(.) + return . + + if(!usr || !src || !(src in usr) || usr.incapacitated()) + if(usr && usr.machine == src) + usr.unset_machine() + return 0 + + if(href_list["hidetext"]) + text_hidden = !text_hidden + + for(var/i in shown_scripture) + if(href_list[i]) + shown_scripture[i] = !shown_scripture[i] + + interact(usr) diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm index cb93d6338fa..8c628c9e8ae 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm @@ -159,7 +159,7 @@ observer_message = "A brass totem rises from the ground, a purple gem appearing in its center!" invokers_required = 2 multiple_invokers_used = TRUE - usage_tip = "If it fails to funnel power into a nearby Sigil of Transmission and fails to disable even one thing, it will disable itself for two minutes." + usage_tip = "If it fails to funnel power into a nearby Sigil of Transmission or the area's APC and fails to disable even one thing, it will disable itself for two minutes." tier = SCRIPTURE_APPLICATION one_per_tile = TRUE sort_priority = 6 diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm index 1600fc21fb1..14a89ec98ba 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm @@ -10,6 +10,7 @@ chant_invocations = list("Punish their blindness!", "Take time, make slow!") chant_amount = 15 chant_interval = 20 + channel_time = 20 required_components = list(BELLIGERENT_EYE = 1) usage_tip = "Useful for crowd control in a populated area and disrupting mass movement." tier = SCRIPTURE_DRIVER diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_judgement.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_judgement.dm index 3297fc80a44..7cd8529055f 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_judgement.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_judgement.dm @@ -6,8 +6,8 @@ /datum/clockwork_scripture/ark_of_the_clockwork_justiciar descname = "Win Condition" name = "Ark of the Clockwork Justiciar" - desc = "Pulls from the power of all of Ratvar's servants and generals to construct a massive machine used to tear apart a rift in spacetime to the Celestial Derelict. This gateway will \ - call forth Ratvar from his exile after some time." + desc = "Pulls from the power of all of Ratvar's servants and generals to construct a massive machine used to tear apart a rift in spacetime to Reebe, the Celestial Derelict.\n\ + This gateway will either call forth Ratvar from his exile if that is the task he has set you, or proselytize the entire station if it is not." invocations = list("ARMORER! FRIGHT! AMPERAGE! VANGUARD! I CALL UPON YOU!!", \ "THE TIME HAS COME FOR OUR MASTER TO BREAK THE CHAINS OF EXILE!!", \ "LEND US YOUR AID! ENGINE COMES!!") diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm index bf1e20f01c8..b48260d4ace 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm @@ -14,7 +14,7 @@ object_path = /obj/structure/destructible/clockwork/ocular_warden creator_message = "You form an ocular warden, which will focus its searing gaze upon nearby unenlightened." observer_message = "A brass eye takes shape and slowly rises into the air, its red iris glaring!" - usage_tip = "Although powerful, the warden is very weak and should optimally be placed behind barricades." + usage_tip = "Although powerful, the warden is very fragile and should optimally be placed behind barricades." tier = SCRIPTURE_SCRIPT one_per_tile = TRUE space_allowed = TRUE @@ -51,7 +51,7 @@ desc = "Equips the invoker and any nearby servants with Ratvarian armor. This armor provides high melee resistance but a weakness to lasers. \ It grows faster to invoke with more nearby servants." invocations = list("Shield me...", "...with the...", "... fragments of Engine!") - channel_time = 110 //effectively 100 because it counts the invoker + channel_time = 100 required_components = list(VANGUARD_COGWHEEL = 2, REPLICANT_ALLOY = 1) consumed_components = list(VANGUARD_COGWHEEL = 1, REPLICANT_ALLOY = 1) usage_tip = "Before using, advise adjacent allies to remove their helmets, external suits, gloves, and shoes." @@ -61,7 +61,7 @@ sort_priority = 4 /datum/clockwork_scripture/fellowship_armory/run_scripture() - for(var/mob/living/L in range(1, invoker)) + for(var/mob/living/L in orange(1, invoker)) if(is_servant_of_ratvar(L) && L.can_speak_vocal()) channel_time = max(channel_time - 10, 0) return ..() @@ -109,7 +109,7 @@ whispered = TRUE object_path = /obj/item/device/mmi/posibrain/soul_vessel creator_message = "You form a soul vessel, which can be used in-hand to attract spirits, or used on an unconscious or dead human to extract their consciousness." - usage_tip = "The vessel can be used as a teleport target for Spatial Gateway, though it is generally better-used by placing it in a shell." + usage_tip = "The vessel can be used as a teleport target for Spatial Gateway, though it is generally better-used by placing it in a shell or cyborg body." tier = SCRIPTURE_SCRIPT space_allowed = TRUE sort_priority = 6 @@ -119,7 +119,7 @@ /datum/clockwork_scripture/create_object/clockwork_proselytizer descname = "Necessary, Converts Objects" name = "Clockwork Proselytizer" - desc = "Forms a device that, when used on certain objects, converts them into their Ratvarian equivalents. It requires replicant alloys to function." + desc = "Forms a device that, when used on certain objects, converts them into their Ratvarian equivalents. It requires replicant alloy to function." invocations = list("With this device...", "...his presence shall be made known.") channel_time = 20 required_components = list(GUVAX_CAPACITOR = 1, REPLICANT_ALLOY = 2) @@ -127,7 +127,7 @@ whispered = TRUE object_path = /obj/item/clockwork/clockwork_proselytizer/preloaded creator_message = "You form a clockwork proselytizer, which is already pre-loaded with a small amount of replicant alloy." - usage_tip = "Clockwork walls cause adjacent tinkerer's caches to generate components passively, making them a vital tool. Clockwork floors heal servants standing on them." + usage_tip = "Clockwork Walls cause nearby tinkerer's caches to generate components passively, making them a vital tool. Clockwork Floors heal toxin damage in Servants standing on them." tier = SCRIPTURE_SCRIPT space_allowed = TRUE sort_priority = 7 diff --git a/code/game/gamemodes/clock_cult/clock_structures/interdiction_lens.dm b/code/game/gamemodes/clock_cult/clock_structures/interdiction_lens.dm index e2f161b7122..1c0cac1267f 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/interdiction_lens.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/interdiction_lens.dm @@ -36,6 +36,7 @@ toggle(0, user) /obj/structure/destructible/clockwork/powered/interdiction_lens/process() + . = ..() if(recharging > world.time) return if(disabled) diff --git a/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm b/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm index e06701c01f1..0634da6d755 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm @@ -8,6 +8,7 @@ inactive_icon = "tinkerers_daemon" max_integrity = 100 obj_integrity = 100 + construction_value = 25 break_message = "The daemon shatters into millions of pieces!" debris = list(/obj/item/clockwork/alloy_shards/large = 2, \ /obj/item/clockwork/alloy_shards/medium = 4, \ diff --git a/code/game/gamemodes/devil/true_devil/_true_devil.dm b/code/game/gamemodes/devil/true_devil/_true_devil.dm index 2e323976414..e8f6c0ff468 100644 --- a/code/game/gamemodes/devil/true_devil/_true_devil.dm +++ b/code/game/gamemodes/devil/true_devil/_true_devil.dm @@ -130,7 +130,7 @@ attack_message = "[user] has [message_verb] [src] with [I]!" if(message_verb) visible_message("[attack_message]", - "[attack_message]", null, COMBAT_MESSAGE_RANGE, user) + "[attack_message]", null, COMBAT_MESSAGE_RANGE) return TRUE /mob/living/carbon/true_devil/Process_Spacemove(movement_dir = 0) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 6ff7bd4743a..aaee37ecabf 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -247,7 +247,7 @@ Class Procs: else user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - user.visible_message("[user.name] smashes against \the [src.name] with its paws.", null, null, COMBAT_MESSAGE_RANGE, user) + user.visible_message("[user.name] smashes against \the [src.name] with its paws.", null, null, COMBAT_MESSAGE_RANGE) take_damage(4, BRUTE, "melee", 1) diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index d7710b28d24..4a8ee45ce79 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -56,7 +56,7 @@ user.changeNext_move(CLICK_CD_MELEE) // Ugh. Ideally we shouldn't be setting cooldowns outside of click code. user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1) - user.visible_message("[user] hits [name]. Nothing happens", null, null, COMBAT_MESSAGE_RANGE, user) + user.visible_message("[user] hits [name]. Nothing happens", null, null, COMBAT_MESSAGE_RANGE) log_message("Attack by hand/paw. Attacker - [user].",1) log_append_to_last("Armor saved.") @@ -94,7 +94,7 @@ log_message("Attack by hulk. Attacker - [user].",1) user.changeNext_move(CLICK_CD_MELEE) add_logs(user, src, "punched", "hulk powers") - user.visible_message("[user] hits [name]. The metal creaks and bends.", null, null, COMBAT_MESSAGE_RANGE, user) + user.visible_message("[user] hits [name]. The metal creaks and bends.", null, null, COMBAT_MESSAGE_RANGE) user.do_attack_animation(src, ATTACK_EFFECT_SMASH) take_damage(15, BRUTE, "melee", 0, get_dir(src, user)) return 1 diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index d8f2c0a205f..73c4802f187 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -455,7 +455,7 @@ . = ..() /obj/item/weapon/twohanded/required/chainsaw/doomslayer - name = "OOOH BABY" + name = "THE GREAT COMMUNICATOR" desc = "VRRRRRRR!!!" armour_penetration = 100 force_on = 30 diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 1e425b7fac8..726fd15e245 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -70,7 +70,7 @@ /obj/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) if(user.a_intent == "harm") ..(user, 1) - visible_message("[user] smashes [src]!", null, null, COMBAT_MESSAGE_RANGE, user) + visible_message("[user] smashes [src]!", null, null, COMBAT_MESSAGE_RANGE) if(density) playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) @@ -134,7 +134,7 @@ return 0 else return 0 - visible_message("[M.name] has hit [src].", null, null, COMBAT_MESSAGE_RANGE, M.occupant) + visible_message("[M.name] has hit [src].", null, null, COMBAT_MESSAGE_RANGE) return take_damage(M.force*3, mech_damtype, "melee", play_soundeffect, get_dir(src, M)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs. /obj/singularity_act() diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 2cf309254a0..9377b9ce084 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -92,15 +92,20 @@ if(!(resistance_flags & INDESTRUCTIBLE)) if(resistance_flags & ON_FIRE) user << "It's on fire!" - var/healthpercent = (obj_integrity/max_integrity) * 100 if(broken) user << "It looks broken." - switch(healthpercent) - if(100 to INFINITY) - user << "It seems pristine and undamaged." - if(50 to 100) - user << "It looks slightly damaged." - if(25 to 50) - user << "It appears heavily damaged." - if(0 to 25) - user << "It's falling apart!" \ No newline at end of file + var/examine_status = examine_status() + if(examine_status) + user << examine_status + +/obj/structure/proc/examine_status() //An overridable proc, mostly for falsewalls. + var/healthpercent = (obj_integrity/max_integrity) * 100 + switch(healthpercent) + if(100 to INFINITY) + return "It seems pristine and undamaged." + if(50 to 100) + return "It looks slightly damaged." + if(25 to 50) + return "It appears heavily damaged." + if(0 to 25) + return "It's falling apart!" diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index f65a36722f5..17474760f0e 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -185,7 +185,7 @@ //prevents remote "kicks" with TK if (!Adjacent(user)) return - user.visible_message("[user] kicks the display case.", null, null, COMBAT_MESSAGE_RANGE, user) + user.visible_message("[user] kicks the display case.", null, null, COMBAT_MESSAGE_RANGE) user.do_attack_animation(src, ATTACK_EFFECT_KICK) take_damage(2) diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index d3df50a5c96..70585b96f26 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -139,6 +139,9 @@ /obj/structure/falsewall/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user) return 0 +/obj/structure/falsewall/examine_status() //So you can't detect falsewalls by examine. + return null + /* * False R-Walls */ diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 9258d7140a0..cf3f5b9ff44 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -43,14 +43,14 @@ /obj/structure/grille/attack_hand(mob/living/user) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_KICK) - user.visible_message("[user] hits [src].", null, null, COMBAT_MESSAGE_RANGE, user) + user.visible_message("[user] hits [src].", null, null, COMBAT_MESSAGE_RANGE) if(!shock(user, 70)) take_damage(rand(5,10), BRUTE, "melee", 1) /obj/structure/grille/attack_alien(mob/living/user) user.do_attack_animation(src) user.changeNext_move(CLICK_CD_MELEE) - user.visible_message("[user] mangles [src].", null, null, COMBAT_MESSAGE_RANGE, user) + user.visible_message("[user] mangles [src].", null, null, COMBAT_MESSAGE_RANGE) if(!shock(user, 70)) take_damage(20, BRUTE, "melee", 1) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 995bd280d75..43acb19bfae 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -448,7 +448,7 @@ /obj/structure/rack/attack_hand(mob/living/user) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_KICK) - user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE, user) + user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE) take_damage(rand(4,8), BRUTE, "melee", 1) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 4337bf630ce..3c786686e92 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -87,7 +87,7 @@ switch(M.damtype) if(BRUTE) playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - visible_message("[M.name] has hit [src]!", null, null, COMBAT_MESSAGE_RANGE, M.occupant) + visible_message("[M.name] has hit [src]!", null, null, COMBAT_MESSAGE_RANGE) if(prob(hardness + M.force) && M.force > 20) dismantle_wall(1) playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm index db549fea546..8930c93bf5f 100644 --- a/code/modules/events/holiday/halloween.dm +++ b/code/modules/events/holiday/halloween.dm @@ -11,10 +11,11 @@ for(var/mob/living/carbon/human/H in mob_list) var/obj/item/weapon/storage/backpack/b = locate() in H.contents new /obj/item/weapon/storage/spooky(b) - if(prob(50)) - H.set_species(/datum/species/skeleton) - else - H.set_species(/datum/species/zombie) + if(ishuman(H) || islizard(H)) + if(prob(50)) + H.set_species(/datum/species/skeleton) + else + H.set_species(/datum/species/zombie) for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in mob_list) Ian.place_on_head(new /obj/item/weapon/bedsheet(Ian)) @@ -53,6 +54,50 @@ if(IsMultiple(activeFor, 4)) spawn_meteors(3, meteorsSPOOKY) //meteor list types defined in gamemode/meteor/meteors.dm +//Creepy clown invasion +/datum/round_event_control/creepy_clowns + name = "Clowns" + typepath = /datum/round_event/creepy_clowns + holidayID = HALLOWEEN + weight = 20 + earliest_start = 0 + +/datum/round_event/creepy_clowns + endWhen = 40 + +/datum/round_event/creepy_clowns/start() + for(var/mob/living/carbon/human/H in living_mob_list) + if(!H.client || !istype(H)) + return + H << "Honk..." + H << 'sound/spookoween/scary_clown_appear.ogg' + var/turf/T = get_turf(H) + if(T) + new /obj/effect/hallucination/simple/clown(T, H, 50) + +/datum/round_event/creepy_clowns/tick() + if(IsMultiple(activeFor, 4)) + for(var/mob/living/carbon/human/H in living_mob_list) + if (prob(66)) + playsound(H.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 100, 1) + if (prob(33)) + var/turf/T = get_turf(H) + if(T) + new /obj/effect/hallucination/simple/clown(T, H, 25) + else if (prob(25)) + var/turf/T = get_turf(H) + if(T) + new /obj/effect/hallucination/simple/clown/scary(T, H, 25) + else if (prob(5)) + var/turf/T = get_turf(H) + if(T) + spawn_atom_to_turf(/obj/effect/mob_spawn/human/corpse/clown, H, 1) + else if (prob(1)) + spawn_atom_to_turf(/mob/living/simple_animal/hostile/retaliate/clown, H, 1) + +/datum/round_event/creepy_clowns/announce() + priority_announce("Honk... Honk... honk... HONK! HONK! HONKHONKHONKHONKHONK", "HONK!", 'sound/spookoween/scary_horn.ogg') + //spooky foods (you can't actually make these when it's not halloween) /obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull name = "skull cookie" diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index c14da947741..cdcb8983ef1 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -206,6 +206,18 @@ Gunshots/explosions/opening doors/less rare audio (done) target << "[xeno_name] scrambles into the ventilation ducts!" qdel(src) +/obj/effect/hallucination/simple/clown + image_icon = 'icons/mob/animal.dmi' + image_state = "clown" + +/obj/effect/hallucination/simple/clown/New(loc,var/mob/living/carbon/T,duration) + ..(loc, T) + name = pick(clown_names) + QDEL_IN(src,duration) + +/obj/effect/hallucination/simple/clown/scary + image_state = "scary_clown" + /obj/effect/hallucination/singularity_scare //Singularity moving towards you. //todo Hide where it moved with fake space images @@ -303,11 +315,12 @@ Gunshots/explosions/opening doors/less rare audio (done) if(target.client) delusions |= A target.client.images |= A - sleep(duration) + QDEL_IN(src, duration) + +/obj/effect/hallucination/delusion/Destroy() for(var/image/I in delusions) if(target.client) target.client.images.Remove(I) - qdel(src) /obj/effect/hallucination/fakeattacker/New(loc,var/mob/living/carbon/T) target = T diff --git a/code/modules/holodeck/area_copy.dm b/code/modules/holodeck/area_copy.dm index d2e4a1d05b2..653aac2f9b3 100644 --- a/code/modules/holodeck/area_copy.dm +++ b/code/modules/holodeck/area_copy.dm @@ -1,7 +1,7 @@ -/proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0, var/atom/newloc = null, var/nerf = 0) +/proc/DuplicateObject(var/atom/original, var/perfectcopy = TRUE, var/sameloc = FALSE, var/atom/newloc = null, var/nerf = FALSE, var/holoitem=FALSE) if(!original) return null - var/obj/O + var/atom/O if(sameloc) O = new original.type(original.loc) @@ -20,15 +20,19 @@ else O.vars[V] = original.vars[V] - if(istype(O)) - O.resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF // holoitems do not burn + if(istype(O, /obj)) + var/obj/N = O + if(holoitem) + N.resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF // holoitems do not burn + if(nerf && istype(O,/obj/item)) var/obj/item/I = O I.damtype = STAMINA // thou shalt not + + N.update_icon() if(istype(O,/obj/machinery)) var/obj/machinery/M = O M.power_change() - O.update_icon() return O @@ -89,13 +93,13 @@ X.icon_state = old_icon_state1 for(var/obj/O in T) - var/obj/O2 = DuplicateObject(O , 1, newloc = X, nerf=nerf_weapons) + var/obj/O2 = DuplicateObject(O , perfect_copy=TRUE, newloc = X, nerf=nerf_weapons, holoitem=TRUE) if(!O2) continue copiedobjs += O2.GetAllContents() for(var/mob/M in T) if(istype(M, /mob/camera)) continue // If we need to check for more mobs, I'll add a variable - var/mob/SM = DuplicateObject(M , 1, newloc = X) + var/mob/SM = DuplicateObject(M , perfect_copy=TRUE, newloc = X, holoitem=TRUE) copiedobjs += SM.GetAllContents() var/global/list/forbidden_vars = list("type","stat","loc","locs","vars", "parent", "parent_type","verbs","ckey","key","x","y","z","contents", "luminosity") diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index e7ca991e69b..cb73bddef64 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -36,7 +36,7 @@ In all, this is a lot like the monkey code. /N M.do_attack_animation(src, ATTACK_EFFECT_BITE) playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) visible_message("[M.name] bites [src]!", \ - "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) adjustBruteLoss(1) add_logs(M, src, "attacked") updatehealth() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm index 0c35197d59f..bd8a1322460 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm @@ -17,7 +17,7 @@ hitverb = "slammed" playsound(loc, "punch", 25, 1, -1) visible_message("[user] has [hitverb] [src]!", \ - "[user] has [hitverb] [src]!", null, COMBAT_MESSAGE_RANGE, user) + "[user] has [hitverb] [src]!", null, COMBAT_MESSAGE_RANGE) return 1 /mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M) @@ -28,7 +28,7 @@ if (prob(90)) playsound(loc, "punch", 25, 1, -1) visible_message("[M] has punched [src]!", \ - "[M] has punched [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has punched [src]!", null, COMBAT_MESSAGE_RANGE) if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of weakening an alien. Paralyse(2) visible_message("[M] has weakened [src]!", \ @@ -39,7 +39,7 @@ else playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) visible_message("[M] has attempted to punch [src]!", \ - "[M] has attempted to punch [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has attempted to punch [src]!", null, COMBAT_MESSAGE_RANGE) if ("disarm") if (!lying) @@ -54,11 +54,11 @@ drop_item() playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) visible_message("[M] has disarmed [src]!", \ - "[M] has disarmed [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has disarmed [src]!", null, COMBAT_MESSAGE_RANGE) else playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) visible_message("[M] has attempted to disarm [src]!",\ - "[M] has attempted to disarm [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has attempted to disarm [src]!", null, COMBAT_MESSAGE_RANGE) diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm index 1a407d945f2..a5b406612ea 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm @@ -7,7 +7,7 @@ playsound(loc, "punch", 25, 1, -1) add_logs(M, src, "attacked") visible_message("[M] has kicked [src]!", \ - "[M] has kicked [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has kicked [src]!", null, COMBAT_MESSAGE_RANGE) if ((stat != DEAD) && (damage > 4.9)) Paralyse(rand(5,10)) @@ -16,7 +16,7 @@ else playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) visible_message("[M] has attempted to kick [src]!", \ - "[M] has attempted to kick [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has attempted to kick [src]!", null, COMBAT_MESSAGE_RANGE) /mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) if(user.a_intent == "harm") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 1d7f6c92da6..f272b85a967 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -332,7 +332,7 @@ updatehealth() visible_message("[M.name] has hit [src]!", \ - "[M.name] has hit [src]!", null, COMBAT_MESSAGE_RANGE, M.occupant) + "[M.name] has hit [src]!", null, COMBAT_MESSAGE_RANGE) add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") else diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 5ec7c528b06..407ca039e84 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -971,7 +971,7 @@ if(!damage || !affecting) playsound(target.loc, user.dna.species.miss_sound, 25, 1, -1) target.visible_message("[user] has attempted to [atk_verb] [target]!",\ - "[user] has attempted to [atk_verb] [target]!", null, COMBAT_MESSAGE_RANGE, user) + "[user] has attempted to [atk_verb] [target]!", null, COMBAT_MESSAGE_RANGE) return 0 @@ -980,7 +980,7 @@ playsound(target.loc, user.dna.species.attack_sound, 25, 1, -1) target.visible_message("[user] has [atk_verb]ed [target]!", \ - "[user] has [atk_verb]ed [target]!", null, COMBAT_MESSAGE_RANGE, user) + "[user] has [atk_verb]ed [target]!", null, COMBAT_MESSAGE_RANGE) if(user.limb_destroyer) target.dismembering_strike(user, affecting.body_zone) @@ -1008,7 +1008,7 @@ if(randn <= 25) playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) target.visible_message("[user] has pushed [target]!", - "[user] has pushed [target]!", null, COMBAT_MESSAGE_RANGE, user) + "[user] has pushed [target]!", null, COMBAT_MESSAGE_RANGE) target.apply_effect(2, WEAKEN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!")) target.forcesay(hit_appends) return @@ -1026,14 +1026,14 @@ if(!talked) //BubbleWrap if(target.drop_item()) target.visible_message("[user] has disarmed [target]!", \ - "[user] has disarmed [target]!", null, COMBAT_MESSAGE_RANGE, user) + "[user] has disarmed [target]!", null, COMBAT_MESSAGE_RANGE) playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) return playsound(target, 'sound/weapons/punchmiss.ogg', 25, 1, -1) target.visible_message("[user] attempted to disarm [target]!", \ - "[user] attemped to disarm [target]!", null, COMBAT_MESSAGE_RANGE, user) + "[user] attemped to disarm [target]!", null, COMBAT_MESSAGE_RANGE) /datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index 99891ec3fde..67dacd174c5 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -666,12 +666,12 @@ meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie specflags = list(NOBREATH,RESISTTEMP,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT, TOXINLOVER) mutant_organs = list(/obj/item/organ/tongue/zombie) - speedmod = 2 /datum/species/zombie/infectious name = "Infectious Zombie" no_equip = list(slot_wear_mask, slot_head) armor = 20 // 120 damage to KO a zombie, which kills it + speedmod = 2 /datum/species/zombie/infectious/spec_life(mob/living/carbon/C) . = ..() diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index 0af56cda546..b9400a3d30f 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -52,7 +52,7 @@ M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) if (prob(75)) visible_message("[M] has punched [name]!", \ - "[M] has punched [name]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has punched [name]!", null, COMBAT_MESSAGE_RANGE) playsound(loc, "punch", 25, 1, -1) var/damage = rand(5, 10) @@ -72,7 +72,7 @@ else playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) visible_message("[M] has attempted to punch [name]!", \ - "[M] has attempted to punch [name]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has attempted to punch [name]!", null, COMBAT_MESSAGE_RANGE) if("disarm") if (!paralysis) M.do_attack_animation(src, ATTACK_EFFECT_DISARM) @@ -81,12 +81,12 @@ playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) add_logs(M, src, "pushed") visible_message("[M] has pushed down [src]!", \ - "[M] has pushed down [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has pushed down [src]!", null, COMBAT_MESSAGE_RANGE) else if(drop_item()) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) visible_message("[M] has disarmed [src]!", \ - "[M] has disarmed [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has disarmed [src]!", null, COMBAT_MESSAGE_RANGE) /mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M) if(..()) //if harm or disarm intent. @@ -99,10 +99,10 @@ if (paralysis < 15) Paralyse(rand(10, 15)) visible_message("[M] has wounded [name]!", \ - "[M] has wounded [name]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has wounded [name]!", null, COMBAT_MESSAGE_RANGE) else visible_message("[M] has slashed [name]!", \ - "[M] has slashed [name]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has slashed [name]!", null, COMBAT_MESSAGE_RANGE) var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) add_logs(M, src, "attacked") @@ -116,18 +116,17 @@ else playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) visible_message("[M] has attempted to lunge at [name]!", \ - "[M] has attempted to lunge at [name]!", null, COMBAT_MESSAGE_RANGE, M) - + "[M] has attempted to lunge at [name]!", null, COMBAT_MESSAGE_RANGE) if (M.a_intent == "disarm") playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) if(prob(95)) Weaken(10) visible_message("[M] has tackled down [name]!", \ - "[M] has tackled down [name]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has tackled down [name]!", null, COMBAT_MESSAGE_RANGE) else if(drop_item()) visible_message("[M] has disarmed [name]!", \ - "[M] has disarmed [name]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has disarmed [name]!", null, COMBAT_MESSAGE_RANGE) add_logs(M, src, "disarmed") updatehealth() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 0b076c59813..d824b58739a 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -110,7 +110,7 @@ return updatehealth() visible_message("[M.name] has hit [src]!", \ - "[M.name] has hit [src]!", null, COMBAT_MESSAGE_RANGE, M.occupant) + "[M.name] has hit [src]!", null, COMBAT_MESSAGE_RANGE) add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") else step_away(src,M) @@ -185,7 +185,7 @@ add_logs(M, src, "attacked") M.do_attack_animation(src) visible_message("The [M.name] glomps [src]!", \ - "The [M.name] glomps [src]!", null, COMBAT_MESSAGE_RANGE, M) + "The [M.name] glomps [src]!", null, COMBAT_MESSAGE_RANGE) return 1 /mob/living/attack_animal(mob/living/simple_animal/M) @@ -198,7 +198,7 @@ playsound(loc, M.attack_sound, 50, 1, 1) M.do_attack_animation(src) visible_message("\The [M] [M.attacktext] [src]!", \ - "\The [M] [M.attacktext] [src]!", null, COMBAT_MESSAGE_RANGE, M) + "\The [M] [M.attacktext] [src]!", null, COMBAT_MESSAGE_RANGE) add_logs(M, src, "attacked") return 1 @@ -217,11 +217,11 @@ add_logs(M, src, "attacked") playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) visible_message("[M.name] bites [src]!", \ - "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) return 1 else visible_message("[M.name] has attempted to bite [src]!", \ - "[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE) return 0 /mob/living/attack_larva(mob/living/carbon/alien/larva/L) @@ -235,12 +235,12 @@ if(prob(90)) add_logs(L, src, "attacked") visible_message("[L.name] bites [src]!", \ - "[L.name] bites [src]!", null, COMBAT_MESSAGE_RANGE, L) + "[L.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) return 1 else visible_message("[L.name] has attempted to bite [src]!", \ - "[L.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE, L) + "[L.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE) return 0 /mob/living/attack_alien(mob/living/carbon/alien/humanoid/M) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 5302d9d1eef..5cdc406c20a 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -858,6 +858,7 @@ var/list/ai_list = list() apc.malfai = parent || src apc.malfhack = TRUE apc.locked = TRUE + apc.coverlocked = TRUE playsound(get_turf(src), 'sound/machines/ding.ogg', 50, 1) src << "Hack complete. \The [apc] is now under your \ diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 7778e4a53c0..7e317bf00c3 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -12,14 +12,14 @@ if(get_active_held_item()) uneq_active() visible_message("[M] disarmed [src]!", \ - "[M] has disabled [src]'s active module!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has disabled [src]'s active module!", null, COMBAT_MESSAGE_RANGE) add_logs(M, src, "disarmed") else Stun(2) step(src,get_dir(M,src)) add_logs(M, src, "pushed") visible_message("[M] has forced back [src]!", \ - "[M] has forced back [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has forced back [src]!", null, COMBAT_MESSAGE_RANGE) playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1) else ..() diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index f40f4bfeed6..c6f5452632b 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -69,7 +69,7 @@ M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) playsound(src.loc, 'sound/effects/bang.ogg', 10, 1) visible_message("[M] punches [src], but doesn't leave a dent.", \ - "[M] punches [src], but doesn't leave a dent.", null, COMBAT_MESSAGE_RANGE, M) + "[M] punches [src], but doesn't leave a dent.", null, COMBAT_MESSAGE_RANGE) return 0 /mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0) diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 4830fd63a2e..c58226a79df 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -15,7 +15,7 @@ if("harm", "disarm") M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) visible_message("[M] [response_harm] [src]!",\ - "[M] [response_harm] [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] [response_harm] [src]!", null, COMBAT_MESSAGE_RANGE) playsound(loc, attacked_sound, 25, 1, -1) attack_threshold_check(harm_intent_damage) add_logs(M, src, "attacked") @@ -27,7 +27,7 @@ ..(user, 1) playsound(loc, "punch", 25, 1, -1) visible_message("[user] has punched [src]!", \ - "[user] has punched [src]!", null, COMBAT_MESSAGE_RANGE, user) + "[user] has punched [src]!", null, COMBAT_MESSAGE_RANGE) adjustBruteLoss(15) return 1 @@ -48,12 +48,12 @@ if(M.a_intent == "disarm") playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) visible_message("[M] [response_disarm] [name]!", \ - "[M] [response_disarm] [name]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] [response_disarm] [name]!", null, COMBAT_MESSAGE_RANGE) add_logs(M, src, "disarmed") else var/damage = rand(15, 30) visible_message("[M] has slashed at [src]!", \ - "[M] has slashed at [src]!", null, COMBAT_MESSAGE_RANGE, M) + "[M] has slashed at [src]!", null, COMBAT_MESSAGE_RANGE) playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) attack_threshold_check(damage) add_logs(M, src, "attacked") diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index c27282e1b8c..a410998bdf5 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -381,37 +381,60 @@ if(issilicon(user) && get_dist(src,user)>1) return src.attack_hand(user) - if (istype(W, /obj/item/weapon/crowbar) && opened) - if (has_electronics==1) - if (terminal) - user << "Disconnect the wires first!" + if (istype(W, /obj/item/weapon/crowbar)) //Using crowbar + if (opened) // a) on open apc + if (has_electronics==1) + if (terminal) + user << "Disconnect the wires first!" + return + playsound(src.loc, W.usesound, 50, 1) + user << "You are trying to remove the power control board..." //lpeters - fixed grammar issues + if(do_after(user, 50/W.toolspeed, target = src)) + if (has_electronics==1) + has_electronics = 0 + if (stat & BROKEN) + user.visible_message(\ + "[user.name] has broken the power control board inside [src.name]!",\ + "You break the charred power control board and remove the remains.", + "You hear a crack.") + return + //ticker.mode:apcs-- //XSI said no and I agreed. -rastaf0 + else if (emagged) // We emag board, not APC's frame + emagged = 0 + user.visible_message(\ + "[user.name] has discarded emaged power control board from [src.name]!",\ + "You discarded shorten board.") + return + else if (malfhack) // AI hacks board, not APC's frame + user.visible_message(\ + "[user.name] has discarded strangely programmed power control board from [src.name]!",\ + "You discarded strangely programmed board.") + malfai = null + malfhack = 0 + return + else + user.visible_message(\ + "[user.name] has removed the power control board from [src.name]!",\ + "You remove the power control board.") + new /obj/item/weapon/electronics/apc(loc) + return + else if (opened!=2) //cover isn't removed + opened = 0 + coverlocked = 1 //closing cover relocks it + update_icon() return - playsound(src.loc, W.usesound, 50, 1) - user << "You are trying to remove the power control board..." //lpeters - fixed grammar issues - if(do_after(user, 50/W.toolspeed, target = src)) - if (has_electronics==1) - has_electronics = 0 - if ((stat & BROKEN) || malfhack) - user.visible_message(\ - "[user.name] has broken the power control board inside [src.name]!",\ - "You break the charred power control board and remove the remains.", - "You hear a crack.") - //ticker.mode:apcs-- //XSI said no and I agreed. -rastaf0 - else - user.visible_message(\ - "[user.name] has removed the power control board from [src.name]!",\ - "You remove the power control board.") - new /obj/item/weapon/electronics/apc(loc) - else if (opened!=2) //cover isn't removed - opened = 0 - update_icon() - else if (istype(W, /obj/item/weapon/crowbar) && !((stat & BROKEN) || malfhack) ) - if(coverlocked && !(stat & MAINT)) - user << "The cover is locked and cannot be opened!" - return - else - opened = 1 - update_icon() + else if (!(stat & BROKEN)) // b) on closed and not broken APC + if(coverlocked && !(stat & MAINT)) // locked... + user << "The cover is locked and cannot be opened!" + return + else if (panel_open) // wires are exposed + user << "Exposed wires prevents you from opening it!" + return + else + opened = 1 + update_icon() + return + else if (istype(W, /obj/item/weapon/stock_parts/cell) && opened) // trying to put a cell inside if(cell) user << "There is a power cell already installed!" @@ -429,13 +452,14 @@ "You insert the power cell.") chargecount = 0 update_icon() + else if (istype(W, /obj/item/weapon/screwdriver)) // haxing if(opened) if (cell) user << "Close the APC first!" //Less hints more mystery! return else - if (has_electronics==1 && terminal) + if (has_electronics==1) has_electronics = 2 stat &= ~MAINT playsound(src.loc, W.usesound, 50, 1) @@ -466,16 +490,24 @@ else if(stat & (BROKEN|MAINT)) user << "Nothing happens!" else - if(allowed(usr) && !wires.is_cut(WIRE_IDSCAN)) + if(allowed(usr) && !wires.is_cut(WIRE_IDSCAN) && !malfhack) locked = !locked user << "You [ locked ? "lock" : "unlock"] the APC interface." update_icon() else user << "Access denied." - else if (istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics!=2) + + else if (istype(W, /obj/item/stack/cable_coil) && opened) if (src.loc:intact) user << "You must remove the floor plating in front of the APC first!" return + else if (terminal) // it already have terminal + user << "This APC is already wired!" + return + else if (has_electronics == 0) + user << "There is nothing to wire!" + return + var/obj/item/stack/cable_coil/C = W if(C.get_amount() < 10) user << "You need ten lengths of cable for APC!" @@ -486,7 +518,7 @@ if(do_after(user, 20, target = src)) if (C.get_amount() < 10 || !C) return - if (C.get_amount() >= 10 && !terminal && opened && has_electronics != 2) + if (C.get_amount() >= 10 && !terminal && opened && has_electronics > 0) var/turf/T = get_turf(src) var/obj/structure/cable/N = T.get_cable_node() if (prob(50) && electrocute_mob(usr, N, N)) @@ -498,21 +530,28 @@ user << "You add cables to the APC frame." make_terminal() terminal.connect_to_network() - else if (istype(W, /obj/item/weapon/wirecutters) && terminal && opened && has_electronics!=2) - terminal.dismantle(user) - else if (istype(W, /obj/item/weapon/electronics/apc) && opened && has_electronics==0 && !((stat & BROKEN) || malfhack)) + else if (istype(W, /obj/item/weapon/wirecutters) && terminal && opened) + terminal.dismantle(user, W) + + else if (istype(W, /obj/item/weapon/electronics/apc) && opened) + if (has_electronics!=0) // there are already electronicks inside + user << "You cannot put the board inside, there already is one!" + return + else if (stat & BROKEN) + user << "You cannot put the board inside, the frame is damaged!" + return + user.visible_message("[user.name] inserts the power control board into [src].", \ "You start to insert the power control board into the frame...") playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) if(do_after(user, 10, target = src)) if(has_electronics==0) has_electronics = 1 + locked = 1 //We placed new, locked board in user << "You place the power control board inside the frame." qdel(W) - else if (istype(W, /obj/item/weapon/electronics/apc) && opened && has_electronics==0 && ((stat & BROKEN) || malfhack)) - user << "You cannot put the board inside, the frame is damaged!" - return + else if (istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics==0 && !terminal) var/obj/item/weapon/weldingtool/WT = W if (WT.get_fuel() < 3) @@ -524,7 +563,7 @@ playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) if(do_after(user, 50/W.toolspeed, target = src)) if(!src || !WT.remove_fuel(3, user)) return - if (emagged || malfhack || (stat & BROKEN) || opened==2) + if ((stat & BROKEN) || opened==2) new /obj/item/stack/sheet/metal(loc) user.visible_message(\ "[user.name] has cut [src] apart with [W].",\ @@ -536,16 +575,20 @@ "You cut the APC frame from the wall.") qdel(src) return - else if (istype(W, /obj/item/wallframe/apc) && opened && emagged) - emagged = 0 - if (opened==2) - opened = 1 - user.visible_message(\ - "[user.name] has replaced the damaged APC frontal panel with a new one.",\ - "You replace the damaged APC frontal panel with a new one.") - qdel(W) - update_icon() - else if (istype(W, /obj/item/wallframe/apc) && opened && ((stat & BROKEN) || malfhack)) + + else if (istype(W, /obj/item/wallframe/apc) && opened) + if (!(stat & BROKEN || opened==2 || obj_integrity < max_integrity)) // There is nothing to repair + user << "You found no reason for repairing this APC" + return + if (!(stat & BROKEN) && opened==2) // Cover is the only thing broken, we do not need to remove elctronicks to replace cover + user.visible_message("[user.name] replaces missing APC's cover.",\ + "You begin to replace APC's cover...") + if(do_after(user, 20, target = src)) // replacing cover is quicker than replacing whole frame + user << "You replace missing APC's cover." + qdel(W) + opened = 1 + update_icon() + return if (has_electronics) user << "You cannot repair this APC until you remove the electronics still inside!" return @@ -556,8 +599,6 @@ qdel(W) stat &= ~BROKEN obj_integrity = max_integrity - malfai = null - malfhack = 0 if (opened==2) opened = 1 update_icon() diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index e20e68a1683..16806b02680 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -164,7 +164,7 @@ //disassembling the terminal if(istype(I, /obj/item/weapon/wirecutters) && terminal && panel_open) - terminal.dismantle(user) + terminal.dismantle(user, I) return //crowbarring it ! diff --git a/code/modules/power/terminal.dm b/code/modules/power/terminal.dm index 68aa7191683..8d2ef8acbd3 100644 --- a/code/modules/power/terminal.dm +++ b/code/modules/power/terminal.dm @@ -38,7 +38,7 @@ /obj/machinery/power/apc/can_terminal_dismantle() . = 0 - if(opened && has_electronics != 2) + if(opened) . = 1 /obj/machinery/power/smes/can_terminal_dismantle() @@ -47,7 +47,7 @@ . = 1 -/obj/machinery/power/terminal/proc/dismantle(mob/living/user) +/obj/machinery/power/terminal/proc/dismantle(mob/living/user, obj/item/W) if(isturf(loc)) var/turf/T = loc if(T.intact) @@ -59,7 +59,7 @@ "You begin to cut the cables...") playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - if(do_after(user, 50, target = src)) + if(do_after(user, 50/W.toolspeed, target = src)) if(master && master.can_terminal_dismantle()) if(prob(50) && electrocute_mob(user, powernet, src)) var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread @@ -73,6 +73,6 @@ /obj/machinery/power/terminal/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/weapon/wirecutters)) - dismantle(user) + dismantle(user, W) else return ..() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 87a2f251b82..75ccabb1c41 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -115,9 +115,9 @@ playsound(user, fire_sound, 50, 1) if(message) if(pointblank) - user.visible_message("[user] fires [src] point blank at [pbtarget]!", null, null, COMBAT_MESSAGE_RANGE, user) + user.visible_message("[user] fires [src] point blank at [pbtarget]!", null, null, COMBAT_MESSAGE_RANGE) else - user.visible_message("[user] fires [src]!", null, null, COMBAT_MESSAGE_RANGE, user) + user.visible_message("[user] fires [src]!", null, null, COMBAT_MESSAGE_RANGE) if(weapon_weight >= WEAPON_MEDIUM) if(user.get_inactive_held_item()) diff --git a/html/changelog.html b/html/changelog.html index 08a6f152118..fd835643218 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,21 @@ -->
+

30 October 2016

+

Mysak0CZ updated:

+ +

bgobandit updated:

+ +

29 October 2016

Chowder McArthor updated:

GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 8f4a92663e3..3c87b5cbb0f 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -7682,3 +7682,15 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. ma44: - rscadd: You can now solidify liquid gold into sheets of gold with frostoil and a very little amount of iron +2016-10-30: + Mysak0CZ: + - bugfix: You no longer need to deconstruct emagged (or AI-hacked) APC to fix them, + replacing board is sufficient + - bugfix: You can no longer unlock AI-hacked APCs + - bugfix: Removing APC's and SMES's terminal no longer ignore current tool's speed + - rscadd: You can repair APC's cover (only if APC is not compleatly broken) by using + APC frame on it + - rscadd: closing APC's cover will lock it + bgobandit: + - rscadd: The creepy clown epidemic has arrived at Space Station 13. + - rscadd: Honk. diff --git a/html/changelogs/AutoChangeLog-pr-21242.yml b/html/changelogs/AutoChangeLog-pr-21242.yml new file mode 100644 index 00000000000..82f85d81c1c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-21242.yml @@ -0,0 +1,4 @@ +author: "Joan" +delete-after: True +changes: + - rscadd: "The Recollection option in the Clockwork Slab has been significantly improved, with a better information to fluff ratio, and the ability to toggle which tiers of scripture that are visible in Recollection."