From 55d30f865ba7d2af86788ab909c0d6e229b0cb42 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 12 Jun 2017 12:20:07 -0500 Subject: [PATCH] upstream-merge-28062 --- code/__DEFINES/clockcult.dm | 6 +- code/__DEFINES/status_effects.dm | 2 + code/datums/status_effects/neutral.dm | 26 ++ .../clock_cult/clock_effects/clock_sigils.dm | 2 +- .../clock_helpers/fabrication_helpers.dm | 372 ++++++++++++++++++ .../clock_items/clock_components.dm | 15 +- .../clock_cult/clock_items/clockwork_slab.dm | 6 +- ..._proselytizer.dm => replica_fabricator.dm} | 179 +++++---- .../clock_scriptures/scripture_revenant.dm | 4 +- .../clock_scriptures/scripture_scripts.dm | 20 +- .../gamemodes/clock_cult/clock_structure.dm | 2 +- .../clock_structures/clock_shells.dm | 2 +- .../ratvar_the_clockwork_justicar.dm | 6 +- .../objects/items/weapons/storage/toolbox.dm | 14 +- .../crates_lockers/closets/secure/security.dm | 1 + code/game/objects/structures/grille.dm | 1 + code/game/objects/structures/lattice.dm | 2 +- .../mining/lavaland/necropolis_chests.dm | 4 +- .../mob/living/silicon/robot/robot_modules.dm | 6 +- .../friendly/drone/extra_drone_types.dm | 62 ++- .../hostile/mining_mobs/basilisk.dm | 3 + .../hostile/mining_mobs/goliath.dm | 4 + .../hostile/mining_mobs/hivelord.dm | 4 + .../hostile/mining_mobs/mining_mobs.dm | 1 + .../hostile/mining_mobs/necropolis_tendril.dm | 6 +- .../guns/energy/kinetic_accelerator.dm | 54 ++- icons/mob/actions.dmi | Bin 194017 -> 194016 bytes icons/obj/clockwork_objects.dmi | Bin 120392 -> 120386 bytes tgstation.dme | 4 +- 29 files changed, 667 insertions(+), 141 deletions(-) create mode 100644 code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm rename code/game/gamemodes/clock_cult/clock_items/{clockwork_proselytizer.dm => replica_fabricator.dm} (54%) diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm index acc0cdc9ab..8b38ca12e5 100644 --- a/code/__DEFINES/clockcult.dm +++ b/code/__DEFINES/clockcult.dm @@ -58,7 +58,7 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us //clockcult power defines #define MIN_CLOCKCULT_POWER 25 //the minimum amount of power clockcult machines will handle gracefully -#define CLOCKCULT_POWER_UNIT (MIN_CLOCKCULT_POWER*100) //standard power amount for clockwork proselytizer costs +#define CLOCKCULT_POWER_UNIT (MIN_CLOCKCULT_POWER*100) //standard power amount for replica fabricator costs #define POWER_STANDARD (CLOCKCULT_POWER_UNIT*0.2) //how much power is in anything else; doesn't matter as much as the following @@ -76,7 +76,7 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us #define POWER_PLASTEEL (CLOCKCULT_POWER_UNIT*0.05) //how much power is in one sheet of plasteel -#define RATVAR_POWER_CHECK "ratvar?" //when passed into can_use_power(), converts it into a check for if ratvar has woken/the proselytizer is debug +#define RATVAR_POWER_CHECK "ratvar?" //when passed into can_use_power(), converts it into a check for if ratvar has woken/the fabricator is debug //Ark defines #define GATEWAY_SUMMON_RATE 1 //the time amount the Gateway to the Celestial Derelict gets each process tick; defaults to 1 per tick @@ -99,7 +99,7 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us #define SIGIL_ACCESS_RANGE 2 //range at which transmission sigils can access power -#define PROSELYTIZER_REPAIR_PER_TICK 4 //how much a proselytizer repairs each tick, and also how many deciseconds each tick is +#define fabricator_REPAIR_PER_TICK 4 //how much a fabricator repairs each tick, and also how many deciseconds each tick is #define OCULAR_WARDEN_EXCLUSION_RANGE 3 //the range at which ocular wardens cannot be placed near other ocular wardens diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 6735ef95e9..cf7acfc543 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -49,3 +49,5 @@ #define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark #define STATUS_EFFECT_CRUSHERDAMAGETRACKING /datum/status_effect/crusher_damage //tracks total kinetic crusher damage on a target + +#define STATUS_EFFECT_SYPHONMARK /datum/status_effect/syphon_mark //tracks kills for the KA death syphon module diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index 0946408323..ae0301762e 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -16,3 +16,29 @@ status_type = STATUS_EFFECT_UNIQUE alert_type = null var/total_damage = 0 + +/datum/status_effect/syphon_mark + id = "syphon_mark" + duration = 50 + status_type = STATUS_EFFECT_MULTIPLE + alert_type = null + on_remove_on_mob_delete = TRUE + var/obj/item/borg/upgrade/modkit/bounty/reward_target + +/datum/status_effect/syphon_mark/on_apply() + if(owner.stat == DEAD) + return FALSE + return ..() + +/datum/status_effect/syphon_mark/proc/get_kill() + if(reward_target) + reward_target.get_kill(owner) + +/datum/status_effect/syphon_mark/tick() + if(owner.stat == DEAD) + get_kill() + qdel(src) + +/datum/status_effect/syphon_mark/on_remove() + get_kill() + . = ..() diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm index 7d8c3eb1f9..79dd366789 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm @@ -204,7 +204,7 @@ else if(!GLOB.ratvar_awakens) to_chat(user, "Hitting the [sigil_name] with brass sheets will convert them to power at a rate of 1 brass sheet to [POWER_FLOOR]W power.") if(!GLOB.ratvar_awakens) - to_chat(user, "You can recharge Clockwork Proselytizers from the [sigil_name].") + to_chat(user, "You can recharge Replica Fabricators from the [sigil_name].") /obj/effect/clockwork/sigil/transmission/attackby(obj/item/I, mob/living/user, params) if(is_servant_of_ratvar(user) && istype(I, /obj/item/stack/tile/brass) && !GLOB.ratvar_awakens) diff --git a/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm new file mode 100644 index 0000000000..1dd976d198 --- /dev/null +++ b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm @@ -0,0 +1,372 @@ +//For the clockwork fabricator, this proc exists to make it easy to customize what the fabricator does when hitting something. + +//if a valid target, returns an associated list in this format; +//list("operation_time" = 15, "new_obj_type" = /obj/structure/window/reinforced/clockwork, "power_cost" = 5, "spawn_dir" = dir, "dir_in_new" = TRUE) +//otherwise, return literally any non-list thing but preferably FALSE +//returning TRUE won't produce the "cannot be fabricated" message and will still prevent fabrication + +/atom/proc/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +/atom/proc/consume_visual(obj/item/clockwork/replica_fabricator/fabricator, power_amount) + if(fabricator.can_use_power(power_amount)) + var/obj/effect/temp_visual/ratvar/beam/itemconsume/B = new /obj/effect/temp_visual/ratvar/beam/itemconsume(get_turf(src)) + B.pixel_x = pixel_x + B.pixel_y = pixel_y + +//Turf conversion +/turf/closed/wall/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //four sheets of metal + return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 4), "spawn_dir" = SOUTH) + +/turf/closed/wall/mineral/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal + return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH) + +/turf/closed/wall/mineral/iron/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal, five rods + return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2) - (POWER_ROD * 5), "spawn_dir" = SOUTH) + +/turf/closed/wall/mineral/cult/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //no metal + return list("operation_time" = 80, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = SOUTH) + +/turf/closed/wall/shuttle/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal + return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH) + +/turf/closed/wall/r_wall/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +/turf/closed/wall/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return list("operation_time" = 50, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = -POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH) + +/turf/open/floor/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + if(floor_tile == /obj/item/stack/tile/plasteel) + new floor_tile(src) + make_plating() + playsound(src, 'sound/items/Crowbar.ogg', 10, 1) //clink + return list("operation_time" = 30, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = POWER_FLOOR, "spawn_dir" = SOUTH) + +/turf/open/floor/plating/asteroid/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +/turf/open/floor/plating/ashplanet/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +/turf/open/floor/plating/lava/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +/turf/open/floor/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + if(locate(/obj/structure/table) in src) + return FALSE + if(locate(/obj/structure/falsewall) in contents) + to_chat(user, "There is a false wall in the way, preventing you from fabricating a clockwork wall on [src].") + return + if(is_blocked_turf(src, TRUE)) + to_chat(user, "Something is in the way, preventing you from fabricating a clockwork wall on [src].") + return TRUE + var/operation_time = 100 + if(!GLOB.ratvar_awakens && fabricator.speed_multiplier > 0) //if ratvar isn't awake, this always takes 10 seconds + operation_time /= fabricator.speed_multiplier + return list("operation_time" = operation_time, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH) + +//False wall conversion +/obj/structure/falsewall/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + var/cost = POWER_WALL_MINUS_FLOOR + if(ispath(mineral, /obj/item/stack/sheet/metal)) + cost -= (POWER_METAL * (2 + mineral_amount)) //four sheets of metal, plus an assumption that the girder is also two + else + cost -= (POWER_METAL * 2) //anything that doesn't use metal just has the girder + return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = cost, "spawn_dir" = SOUTH) + +/obj/structure/falsewall/iron/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal, two rods; special assumption + return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = POWER_WALL_MINUS_FLOOR - (POWER_METAL * 2) - (POWER_ROD * 2), "spawn_dir" = SOUTH) + +/obj/structure/falsewall/reinforced/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +/obj/structure/falsewall/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +//Metal conversion +/obj/item/stack/tile/plasteel/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + if(source) + return FALSE + var/amount_temp = get_amount() + var/no_delete = FALSE + if(amount_temp < 2) + to_chat(user, "You need at least 2 floor tiles to convert into power.") + return TRUE + if(IsOdd(amount_temp)) + amount_temp-- + no_delete = TRUE + use(amount_temp) + amount_temp *= 12.5 //each tile is 12.5 power so this is 2 tiles to 25 power + consume_visual(fabricator, amount_temp) + return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = -amount_temp, "spawn_dir" = SOUTH, "no_target_deletion" = no_delete) + +/obj/item/stack/rods/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + if(source) + return FALSE + var/power_amount = -(amount*POWER_ROD) + consume_visual(fabricator, power_amount) + return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH) + +/obj/item/stack/sheet/metal/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + if(source) + return FALSE + var/power_amount = -(amount*POWER_METAL) + consume_visual(fabricator, power_amount) + return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH) + +/obj/item/stack/sheet/plasteel/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + if(source) + return FALSE + var/power_amount = -(amount*POWER_PLASTEEL) + consume_visual(fabricator, power_amount) + return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH) + +//Brass directly to power +/obj/item/stack/tile/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + if(source) + return FALSE + var/power_amount = -(amount*POWER_FLOOR) + consume_visual(fabricator, power_amount) + return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH) + +//Airlock conversion +/obj/machinery/door/airlock/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + var/doortype = /obj/machinery/door/airlock/clockwork + if(glass) + doortype = /obj/machinery/door/airlock/clockwork/brass + return list("operation_time" = 60, "new_obj_type" = doortype, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = dir) + +/obj/machinery/door/airlock/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +//Table conversion +/obj/structure/table/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + var/fabrication_cost = POWER_STANDARD + if(framestack == /obj/item/stack/rods) + fabrication_cost -= POWER_ROD*framestackamount + else if(framestack == /obj/item/stack/tile/brass) + fabrication_cost -= POWER_FLOOR*framestackamount + if(buildstack == /obj/item/stack/sheet/metal) + fabrication_cost -= POWER_METAL*buildstackamount + else if(buildstack == /obj/item/stack/sheet/plasteel) + fabrication_cost -= POWER_PLASTEEL*buildstackamount + return list("operation_time" = 20, "new_obj_type" = /obj/structure/table/reinforced/brass, "power_cost" = fabrication_cost, "spawn_dir" = SOUTH) + +/obj/structure/table/reinforced/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +/obj/structure/table_frame/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + var/fabrication_cost = POWER_FLOOR + if(framestack == /obj/item/stack/rods) + fabrication_cost -= POWER_ROD*framestackamount + else if(framestack == /obj/item/stack/tile/brass) + fabrication_cost -= POWER_FLOOR*framestackamount + return list("operation_time" = 10, "new_obj_type" = /obj/structure/table_frame/brass, "power_cost" = fabrication_cost, "spawn_dir" = SOUTH) + +/obj/structure/table_frame/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +//Window conversion +/obj/structure/window/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + var/windowtype = /obj/structure/window/reinforced/clockwork + var/new_dir = TRUE + var/fabrication_time = 15 + var/fabrication_cost = POWER_FLOOR + if(fulltile) + windowtype = /obj/structure/window/reinforced/clockwork/fulltile + new_dir = FALSE + fabrication_time = 30 + fabrication_cost = POWER_STANDARD + if(reinf) + fabrication_cost -= POWER_ROD + if(reinf) + fabrication_cost -= POWER_ROD + for(var/obj/structure/grille/G in get_turf(src)) + INVOKE_ASYNC(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricate, G, user) + return list("operation_time" = fabrication_time, "new_obj_type" = windowtype, "power_cost" = fabrication_cost, "spawn_dir" = dir, "dir_in_new" = new_dir) + +/obj/structure/window/reinforced/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +//Windoor conversion +/obj/machinery/door/window/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return list("operation_time" = 30, "new_obj_type" = /obj/machinery/door/window/clockwork, "power_cost" = POWER_STANDARD, "spawn_dir" = dir, "dir_in_new" = TRUE) + +/obj/machinery/door/window/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +//Grille conversion +/obj/structure/grille/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + var/grilletype = /obj/structure/grille/ratvar + var/fabrication_time = 15 + if(broken) + grilletype = /obj/structure/grille/ratvar/broken + fabrication_time = 5 + return list("operation_time" = fabrication_time, "new_obj_type" = grilletype, "power_cost" = 0, "spawn_dir" = dir) + +/obj/structure/grille/ratvar/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +//Lattice conversion +/obj/structure/lattice/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE) + +/obj/structure/lattice/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + ratvar_act() //just in case we're the wrong type for some reason?? + return FALSE + +/obj/structure/lattice/catwalk/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/catwalk/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE) + +/obj/structure/lattice/catwalk/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + return FALSE + +//Girder conversion +/obj/structure/girder/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + var/fabrication_cost = POWER_GEAR - (POWER_METAL * 2) + if(state == GIRDER_REINF_STRUTS || state == GIRDER_REINF) + fabrication_cost -= POWER_PLASTEEL + return list("operation_time" = 20, "new_obj_type" = /obj/structure/destructible/clockwork/wall_gear, "power_cost" = fabrication_cost, "spawn_dir" = SOUTH) + +//Hitting a clockwork structure will try to repair it. +/obj/structure/destructible/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + . = TRUE + var/list/repair_values = list() + if(!fabricator.fabricator_repair_checks(repair_values, src, user)) + return + user.visible_message("[user]'s [fabricator.name] starts covering [src] in glowing orange energy...", \ + "You start repairing [src]...") + fabricator.repairing = src + while(fabricator && user && src) + if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \ + extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE))) + break + obj_integrity = Clamp(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity) + fabricator.modify_stored_power(-repair_values["power_required"]) + playsound(src, 'sound/machines/click.ogg', 50, 1) + + if(fabricator) + fabricator.repairing = null + if(user) + user.visible_message("[user]'s [fabricator.name] stops covering [src] with glowing orange energy.", \ + "You finish repairing [src]. It is now at [obj_integrity]/[max_integrity] integrity.") + +//Hitting a sigil of transmission will try to charge from it. +/obj/effect/clockwork/sigil/transmission/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + . = TRUE + var/list/charge_values = list() + if(!fabricator.sigil_charge_checks(charge_values, src, user)) + return + user.visible_message("[user]'s [fabricator.name] starts draining glowing orange energy from [src]...", \ + "You start recharging your [fabricator.name]...") + fabricator.recharging = src + while(fabricator && user && src) + if(!do_after(user, 10, target = src, extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/sigil_charge_checks, charge_values, src, user, TRUE))) + break + modify_charge(charge_values["power_gain"]) + fabricator.modify_stored_power(charge_values["power_gain"]) + playsound(src, 'sound/effects/light_flicker.ogg', charge_values["power_gain"] * 0.1, 1) + + if(fabricator) + fabricator.recharging = null + if(user) + user.visible_message("[user]'s [fabricator.name] stops draining glowing orange energy from [src].", \ + "You finish recharging your [fabricator.name]. It now contains [fabricator.get_power()]W/[fabricator.get_max_power()]W power.") + +//Fabricator mob heal proc, to avoid as much copypaste as possible. +/mob/living/proc/fabricator_heal(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator) + var/list/repair_values = list() + if(!fabricator.fabricator_repair_checks(repair_values, src, user)) + return + user.visible_message("[user]'s [fabricator.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...", \ + "You start repairin[src == user ? "g yourself" : "g [src]"]...") + fabricator.repairing = src + while(fabricator && user && src) + if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \ + extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE))) + break + fabricator_heal_tick(repair_values["healing_for_cycle"]) + fabricator.modify_stored_power(-repair_values["power_required"]) + playsound(src, 'sound/machines/click.ogg', 50, 1) + + if(fabricator) + fabricator.repairing = null + + return TRUE + +/mob/living/proc/fabricator_heal_tick(amount) + var/static/list/damage_heal_order = list(BRUTE, BURN, TOX, OXY) + heal_ordered_damage(amount, damage_heal_order) + +/mob/living/simple_animal/fabricator_heal_tick(amount) + adjustHealth(-amount) + +//Hitting a ratvar'd silicon will also try to repair it. +/mob/living/silicon/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + . = TRUE + if(health == maxHealth) //if we're at maximum health, replace the turf under us + return FALSE + else if(fabricator_heal(user, fabricator) && user) + user.visible_message("[user]'s [fabricator.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.", \ + "You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at [abs(HEALTH_THRESHOLD_DEAD - health)]/[abs(HEALTH_THRESHOLD_DEAD - maxHealth)] health.") + +//Same with clockwork mobs. +/mob/living/simple_animal/hostile/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + . = TRUE + if(health == maxHealth) //if we're at maximum health, replace the turf under us + return FALSE + else if(fabricator_heal(user, fabricator) && user) + user.visible_message("[user]'s [fabricator.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.", \ + "You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at [health]/[maxHealth] health.") + +//Cogscarabs get special interaction because they're drones and have innate self-heals/revives. +/mob/living/simple_animal/drone/cogscarab/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) + . = TRUE + if(stat == DEAD) + try_reactivate(user) //if we're dead, try to repair us + return + if(health == maxHealth) + return FALSE + else if(!(flags & GODMODE)) + user.visible_message("[user]'s [fabricator.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...", \ + "You start repairin[src == user ? "g yourself" : "g [src]"]...") + fabricator.repairing = src + if(do_after(user, (maxHealth - health)*2, target=src)) + adjustHealth(-maxHealth) + user.visible_message("[user]'s [fabricator.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.", \ + "You finish repairin[src == user ? "g yourself" : "g [src]"].") + if(fabricator) + fabricator.repairing = null + +//Convert shards and gear bits directly to power +/obj/item/clockwork/alloy_shards/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount) + if(!power_amount) + power_amount = -POWER_STANDARD + consume_visual(fabricator, power_amount) + if(!silent) //looper no looping + for(var/obj/item/clockwork/alloy_shards/S in get_turf(src)) //convert all other shards in the turf if we can + if(S == src) + continue //we want the shards to be fabricated after the main shard, thus this delay + addtimer(CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricate, S, user, TRUE), 0) + return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH) + +/obj/item/clockwork/alloy_shards/medium/gear_bit/large/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount) + if(!power_amount) + power_amount = -(CLOCKCULT_POWER_UNIT*0.08) + return ..() + +/obj/item/clockwork/alloy_shards/large/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount) + if(!power_amount) + power_amount = -(CLOCKCULT_POWER_UNIT*0.06) + return ..() + +/obj/item/clockwork/alloy_shards/medium/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount) + if(!power_amount) + power_amount = -(CLOCKCULT_POWER_UNIT*0.04) + return ..() + +/obj/item/clockwork/alloy_shards/small/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount) + if(!power_amount) + power_amount = -(CLOCKCULT_POWER_UNIT*0.02) + return ..() diff --git a/code/game/gamemodes/clock_cult/clock_items/clock_components.dm b/code/game/gamemodes/clock_cult/clock_items/clock_components.dm index f64b361ac1..7550aea74f 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clock_components.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clock_components.dm @@ -153,11 +153,11 @@ icon_state = "obelisk_prism" w_class = WEIGHT_CLASS_NORMAL -//Shards of Alloy, suitable only for proselytization. +//Shards of Alloy, suitable only as a source of power for a replica fabricator. /obj/item/clockwork/alloy_shards name = "replicant alloy shards" desc = "Broken shards of some oddly malleable metal. They occasionally move and seem to glow." - clockwork_desc = "Broken shards of replicant alloy. Can be proselytized for additional power." + clockwork_desc = "Broken shards of replicant alloy." icon_state = "alloy_shards" resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF var/randomsinglesprite = FALSE @@ -172,10 +172,15 @@ pixel_x = rand(-sprite_shift, sprite_shift) pixel_y = rand(-sprite_shift, sprite_shift) +/obj/item/clockwork/alloy_shards/examine(mob/user) + ..() + if(is_servant_of_ratvar(user) || isobserver(user)) + to_chat(user, "Can be consumed by a replica fabricator as a source of power.") + /obj/item/clockwork/alloy_shards/proc/replace_name_desc() name = "replicant alloy shard" desc = "A broken shard of some oddly malleable metal. It occasionally moves and seems to glow." - clockwork_desc = "A broken shard of replicant alloy. Can be proselytized for additional power." + clockwork_desc = "A broken shard of replicant alloy." /obj/item/clockwork/alloy_shards/large w_class = WEIGHT_CLASS_TINY @@ -197,7 +202,7 @@ /obj/item/clockwork/alloy_shards/medium/gear_bit/replace_name_desc() name = "gear bit" desc = "A broken chunk of a gear. You want it." - clockwork_desc = "A broken chunk of a gear. Can be proselytized for additional power." + clockwork_desc = "A broken chunk of a gear." /obj/item/clockwork/alloy_shards/medium/gear_bit/large //gives more power @@ -215,5 +220,5 @@ /obj/item/clockwork/alloy_shards/pinion_lock name = "pinion lock" desc = "A dented and scratched gear. It's very heavy." - clockwork_desc = "A broken gear lock for pinion airlocks. Can be proselytized for additional power." + clockwork_desc = "A broken gear lock for pinion airlocks" icon_state = "pinion_lock" 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 4bdbf086d1..38a2cdadc0 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm @@ -41,7 +41,7 @@ if(!is_servant_of_ratvar(user)) add_servant_of_ratvar(user) -/obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and proselytizer +/obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and fabricator clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture.\n\ Hitting a slab, a Servant with a slab, or a cache will transfer this slab's components into the target, the target's slab, or the global cache, respectively." quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \ @@ -49,7 +49,7 @@ maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more actions_types = list() -/obj/item/clockwork/slab/cyborg/engineer //five scriptures, plus a proselytizer +/obj/item/clockwork/slab/cyborg/engineer //five scriptures, plus a fabricator quickbound = list(/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/cogscarab, \ /datum/clockwork_scripture/create_object/soul_vessel, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/interdiction_lens) @@ -65,7 +65,7 @@ quickbound = list(/datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/taunting_tirade, \ /datum/clockwork_scripture/channeled/volt_void/cyborg) -/obj/item/clockwork/slab/cyborg/janitor //five scriptures, plus a proselytizer +/obj/item/clockwork/slab/cyborg/janitor //five scriptures, plus a fabricator quickbound = list(/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \ /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor, /datum/clockwork_scripture/create_object/tinkerers_daemon) diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm b/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm similarity index 54% rename from code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm rename to code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm index aa174adcd8..788d581810 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm +++ b/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm @@ -1,51 +1,48 @@ -//Clockwork proselytizer: Converts applicable objects to Ratvarian variants. -/obj/item/clockwork/clockwork_proselytizer - name = "clockwork proselytizer" +//Replica Fabricator: Converts applicable objects to Ratvarian variants. +/obj/item/clockwork/replica_fabricator + name = "replica fabricator" desc = "An odd, L-shaped device that hums with energy." clockwork_desc = "A device that allows the replacing of mundane objects with Ratvarian variants. It requires power to function." - icon_state = "clockwork_proselytizer" + icon_state = "replica_fabricator" w_class = WEIGHT_CLASS_NORMAL force = 5 flags = NOBLUDGEON var/stored_power = 0 //Requires power to function var/max_power = CLOCKCULT_POWER_UNIT * 10 var/uses_power = TRUE - var/metal_to_power = FALSE var/repairing = null //what we're currently repairing, if anything var/obj/effect/clockwork/sigil/transmission/recharging = null //the sigil we're charging from, if any - var/speed_multiplier = 1 //how fast this proselytizer works + var/speed_multiplier = 1 //how fast this fabricator works var/charge_rate = MIN_CLOCKCULT_POWER //how much power we gain every two seconds var/charge_delay = 2 //how many proccess ticks remain before we can start to charge -/obj/item/clockwork/clockwork_proselytizer/preloaded +/obj/item/clockwork/replica_fabricator/preloaded stored_power = POWER_WALL_MINUS_FLOOR+POWER_WALL_TOTAL -/obj/item/clockwork/clockwork_proselytizer/scarab - name = "scarab proselytizer" - clockwork_desc = "A cogscarab's internal proselytizer. It can only be successfully used by a cogscarab and requires power to function." - metal_to_power = TRUE +/obj/item/clockwork/replica_fabricator/scarab + name = "scarab fabricator" + clockwork_desc = "A cogscarab's internal fabricator. It can only be successfully used by a cogscarab and requires power to function." item_state = "nothing" w_class = WEIGHT_CLASS_TINY speed_multiplier = 0.5 charge_rate = MIN_CLOCKCULT_POWER * 2 var/debug = FALSE -/obj/item/clockwork/clockwork_proselytizer/scarab/proselytize(atom/target, mob/living/user) +/obj/item/clockwork/replica_fabricator/scarab/fabricate(atom/target, mob/living/user) if(!debug && !isdrone(user)) return 0 return ..() -/obj/item/clockwork/clockwork_proselytizer/scarab/debug - clockwork_desc = "A cogscarab's internal proselytizer. It can convert nearly any object into a Ratvarian variant." +/obj/item/clockwork/replica_fabricator/scarab/debug + clockwork_desc = "A cogscarab's internal fabricator. It can convert nearly any object into a Ratvarian variant." uses_power = FALSE debug = TRUE -/obj/item/clockwork/clockwork_proselytizer/cyborg - name = "cyborg proselytizer" - clockwork_desc = "A cyborg's internal proselytizer. It is capable of using the cyborg's power in addition to stored power." - metal_to_power = TRUE +/obj/item/clockwork/replica_fabricator/cyborg + name = "cyborg fabricator" + clockwork_desc = "A cyborg's internal fabricator. It is capable of using the cyborg's power in addition to stored power." -/obj/item/clockwork/clockwork_proselytizer/cyborg/get_power() //returns power and cyborg's power +/obj/item/clockwork/replica_fabricator/cyborg/get_power() //returns power and cyborg's power var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living) var/borg_power = 0 var/current_charge = 0 @@ -56,14 +53,14 @@ borg_power += MIN_CLOCKCULT_POWER return ..() + borg_power -/obj/item/clockwork/clockwork_proselytizer/cyborg/get_max_power() +/obj/item/clockwork/replica_fabricator/cyborg/get_max_power() var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living) var/cell_maxcharge = 0 if(istype(R) && R.cell) cell_maxcharge = R.cell.maxcharge return ..() + cell_maxcharge -/obj/item/clockwork/clockwork_proselytizer/cyborg/can_use_power(amount) +/obj/item/clockwork/replica_fabricator/cyborg/can_use_power(amount) if(amount != RATVAR_POWER_CHECK) var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living) var/current_charge = 0 @@ -76,7 +73,7 @@ return FALSE . = ..() -/obj/item/clockwork/clockwork_proselytizer/cyborg/modify_stored_power(amount) +/obj/item/clockwork/replica_fabricator/cyborg/modify_stored_power(amount) var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living) if(istype(R) && R.cell && amount) if(amount < 0) @@ -89,15 +86,15 @@ amount -= MIN_CLOCKCULT_POWER . = ..() -/obj/item/clockwork/clockwork_proselytizer/Initialize() +/obj/item/clockwork/replica_fabricator/Initialize() . = ..() START_PROCESSING(SSobj, src) -/obj/item/clockwork/clockwork_proselytizer/Destroy() +/obj/item/clockwork/replica_fabricator/Destroy() STOP_PROCESSING(SSobj, src) return ..() -/obj/item/clockwork/clockwork_proselytizer/process() +/obj/item/clockwork/replica_fabricator/process() if(!charge_rate) return var/mob/living/L = get_atom_on_turf(src, /mob/living) @@ -106,14 +103,14 @@ charge_delay-- return modify_stored_power(charge_rate) - for(var/obj/item/clockwork/clockwork_proselytizer/S in L.GetAllContents()) //no multiple proselytizers + for(var/obj/item/clockwork/replica_fabricator/S in L.GetAllContents()) //no multiple fabricators if(S == src) continue S.charge_delay = 2 else charge_delay = 2 -/obj/item/clockwork/clockwork_proselytizer/ratvar_act() +/obj/item/clockwork/replica_fabricator/ratvar_act() if(GLOB.nezbere_invoked) charge_rate = 1250 else @@ -125,21 +122,19 @@ uses_power = initial(uses_power) speed_multiplier = initial(speed_multiplier) -/obj/item/clockwork/clockwork_proselytizer/examine(mob/living/user) +/obj/item/clockwork/replica_fabricator/examine(mob/living/user) ..() if(is_servant_of_ratvar(user) || isobserver(user)) - to_chat(user, "Can be used to convert walls, floors, windows, airlocks, and a variety of other objects to clockwork variants.") - to_chat(user, "Can also form some objects into Brass sheets, as well as reform Clockwork Walls into Clockwork Floors, and vice versa.") + to_chat(user, "Can be used to replace walls, floors, tables, windows, windoors, and airlocks with Clockwork variants.") + to_chat(user, "Can construct Clockwork Walls on Clockwork Floors and deconstruct Clockwork Walls to Clockwork Floors.") if(uses_power) - if(metal_to_power) - to_chat(user, "It can convert rods, metal, plasteel, and brass to power at rates of 1:[POWER_ROD]W, 1:[POWER_METAL]W, \ - 1:[POWER_PLASTEEL]W, and 1:[POWER_FLOOR]W, respectively.") - else - to_chat(user, "It can convert brass to power at a rate of 1:[POWER_FLOOR]W.") - to_chat(user, "It is storing [get_power()]W/[get_max_power()]W of power, and is gaining [charge_rate*0.5]W of power per second.") + to_chat(user, "It can consume floor tiles, rods, metal, and plasteel for power at rates of 2:[POWER_ROD]W, 1:[POWER_ROD]W, 1:[POWER_METAL]W, \ + and 1:[POWER_PLASTEEL]W, respectively.") + to_chat(user, "It can also consume brass sheets for power at a rate of 1:[POWER_FLOOR]W.") + to_chat(user, "It is storing [get_power()]W/[get_max_power()]W of power[charge_rate ? ", and is gaining [charge_rate*0.5]W of power per second":""].") to_chat(user, "Use it in-hand to produce 5 brass sheets at a cost of [POWER_WALL_TOTAL]W power.") -/obj/item/clockwork/clockwork_proselytizer/attack_self(mob/living/user) +/obj/item/clockwork/replica_fabricator/attack_self(mob/living/user) if(is_servant_of_ratvar(user)) if(uses_power) if(!can_use_power(POWER_WALL_TOTAL)) @@ -148,24 +143,24 @@ modify_stored_power(-POWER_WALL_TOTAL) playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) new/obj/item/stack/tile/brass(user.loc, 5) - to_chat(user, "You user [stored_power ? "some":"all"] of [src]'s power to produce some brass sheets. It now stores [get_power()]W/[get_max_power()]W of power.") + to_chat(user, "You use [stored_power ? "some":"all"] of [src]'s power to produce 5 brass sheets. It now stores [get_power()]W/[get_max_power()]W of power.") -/obj/item/clockwork/clockwork_proselytizer/pre_attackby(atom/target, mob/living/user, params) +/obj/item/clockwork/replica_fabricator/pre_attackby(atom/target, mob/living/user, params) if(!target || !user || !is_servant_of_ratvar(user) || istype(target, /obj/item/weapon/storage)) return TRUE - return proselytize(target, user) + return fabricate(target, user) -/obj/item/clockwork/clockwork_proselytizer/proc/get_power() +/obj/item/clockwork/replica_fabricator/proc/get_power() return stored_power -/obj/item/clockwork/clockwork_proselytizer/proc/get_max_power() +/obj/item/clockwork/replica_fabricator/proc/get_max_power() return max_power -/obj/item/clockwork/clockwork_proselytizer/proc/modify_stored_power(amount) +/obj/item/clockwork/replica_fabricator/proc/modify_stored_power(amount) stored_power = Clamp(stored_power + amount, 0, max_power) return TRUE -/obj/item/clockwork/clockwork_proselytizer/proc/can_use_power(amount) +/obj/item/clockwork/replica_fabricator/proc/can_use_power(amount) if(amount == RATVAR_POWER_CHECK) if(GLOB.ratvar_awakens || !uses_power) return TRUE @@ -178,7 +173,7 @@ return TRUE //A note here; return values are for if we CAN BE PUT ON A TABLE, not IF WE ARE SUCCESSFUL, unless no_table_check is TRUE -/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user, silent, no_table_check) +/obj/item/clockwork/replica_fabricator/proc/fabricate(atom/target, mob/living/user, silent, no_table_check) if(!target || !user) return FALSE if(repairing) @@ -189,59 +184,77 @@ if(!silent) to_chat(user, "You are currently recharging [src] from the [recharging.sigil_name]!") return FALSE - var/list/proselytize_values = target.proselytize_vals(user, src, silent) //relevant values for proselytizing stuff, given as an associated list - if(!islist(proselytize_values)) - if(proselytize_values != TRUE) //if we get true, fail, but don't send a message for whatever reason - if(!isturf(target)) //otherwise, if we didn't get TRUE and the original target wasn't a turf, try to proselytize the turf - return proselytize(get_turf(target), user, no_table_check) + var/list/fabrication_values = target.fabrication_vals(user, src, silent) //relevant values for fabricating stuff, given as an associated list + if(!islist(fabrication_values)) + if(fabrication_values != TRUE) //if we get true, fail, but don't send a message for whatever reason + if(!isturf(target)) //otherwise, if we didn't get TRUE and the original target wasn't a turf, try to fabricate the turf + return fabricate(get_turf(target), user, no_table_check) if(!silent) - to_chat(user, "[target] cannot be proselytized!") + to_chat(user, "[target] cannot be fabricated!") if(!no_table_check) return TRUE return FALSE if(can_use_power(RATVAR_POWER_CHECK)) - proselytize_values["power_cost"] = 0 + fabrication_values["power_cost"] = 0 var/turf/Y = get_turf(user) if(!Y || (Y.z != ZLEVEL_STATION && Y.z != ZLEVEL_CENTCOM && Y.z != ZLEVEL_MINING && Y.z != ZLEVEL_LAVALAND)) - proselytize_values["operation_time"] *= 2 - if(proselytize_values["power_cost"] > 0) - proselytize_values["power_cost"] *= 2 + fabrication_values["operation_time"] *= 2 + if(fabrication_values["power_cost"] > 0) + fabrication_values["power_cost"] *= 2 var/target_type = target.type - if(!proselytize_checks(proselytize_values, target, target_type, user, silent)) + if(!fabricate_checks(fabrication_values, target, target_type, user, silent)) return FALSE - proselytize_values["operation_time"] *= speed_multiplier + fabrication_values["operation_time"] *= speed_multiplier playsound(target, 'sound/machines/click.ogg', 50, 1) - if(proselytize_values["operation_time"]) + if(fabrication_values["operation_time"]) if(!silent) - user.visible_message("[user]'s [name] begins tearing apart [target]!", "You begin proselytizing [target]...") - if(!do_after(user, proselytize_values["operation_time"], target = target, extra_checks = CALLBACK(src, .proc/proselytize_checks, proselytize_values, target, target_type, user, TRUE))) + var/atom/A = fabrication_values["new_obj_type"] + if(A) + user.visible_message("[user]'s [name] starts ripping [target] apart!", \ + "You start fabricating \a [initial(A.name)] from [target]...") + else + user.visible_message("[user]'s [name] starts consuming [target]!", \ + "Your [name] starts consuming [target]...") + if(!do_after(user, fabrication_values["operation_time"], target = target, extra_checks = CALLBACK(src, .proc/fabricate_checks, fabrication_values, target, target_type, user, TRUE))) return FALSE if(!silent) - user.visible_message("[user]'s [name] covers [target] in golden energy!", "You proselytize [target].") + var/atom/A = fabrication_values["new_obj_type"] + if(A) + user.visible_message("[user]'s [name] replaces [target] with \a [initial(A.name)]!", \ + "You fabricate \a [initial(A.name)] from [target].") + else + user.visible_message("[user]'s [name] consumes [target]!", \ + "Your [name] consumes [target].") else if(!silent) - user.visible_message("[user]'s [name] tears apart [target], covering it in golden energy!", "You proselytize [target].") + var/atom/A = fabrication_values["new_obj_type"] + if(A) + user.visible_message("[user]'s [name] rips apart [target], replacing it with \a [initial(A.name)]!", \ + "You fabricate \a [initial(A.name)] from [target].") + else + user.visible_message("[user]'s [name] rapidly consumes [target]!", \ + "Your [name] consumes [target].") playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - var/new_thing_type = proselytize_values["new_obj_type"] + var/new_thing_type = fabrication_values["new_obj_type"] if(isturf(target)) //if our target is a turf, we're just going to ChangeTurf it and assume it'll work out. var/turf/T = target T.ChangeTurf(new_thing_type) else if(new_thing_type) - if(proselytize_values["dir_in_new"]) - new new_thing_type(get_turf(target), proselytize_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New() + if(fabrication_values["dir_in_new"]) + new new_thing_type(get_turf(target), fabrication_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New() else var/atom/A = new new_thing_type(get_turf(target)) - A.setDir(proselytize_values["spawn_dir"]) - if(!proselytize_values["no_target_deletion"]) //for some cases where proselytize_vals() modifies the object but doesn't want it deleted + A.setDir(fabrication_values["spawn_dir"]) + if(!fabrication_values["no_target_deletion"]) //for some cases where fabrication_vals() modifies the object but doesn't want it deleted qdel(target) - modify_stored_power(-proselytize_values["power_cost"]) + modify_stored_power(-fabrication_values["power_cost"]) if(no_table_check) return TRUE return FALSE @@ -250,28 +263,34 @@ //What these procs do is they take an existing list of values, which they then modify. //This(modifying an existing object, in this case the list) is the only way to get information OUT of a do_after callback, which this is used as. -//The proselytize check proc. -/obj/item/clockwork/clockwork_proselytizer/proc/proselytize_checks(list/proselytize_values, atom/target, expected_type, mob/user, silent) //checked constantly while proselytizing - if(!islist(proselytize_values) || QDELETED(target) || QDELETED(user)) +//The fabricate check proc. +/obj/item/clockwork/replica_fabricator/proc/fabricate_checks(list/fabrication_values, atom/target, expected_type, mob/user, silent) //checked constantly while fabricating + if(!islist(fabrication_values) || QDELETED(target) || QDELETED(user)) return FALSE if(repairing || recharging) return FALSE if(target.type != expected_type) return FALSE if(can_use_power(RATVAR_POWER_CHECK)) - proselytize_values["power_cost"] = 0 - if(!can_use_power(proselytize_values["power_cost"])) - if(stored_power - proselytize_values["power_cost"] < 0) + fabrication_values["power_cost"] = 0 + if(!can_use_power(fabrication_values["power_cost"])) + if(stored_power - fabrication_values["power_cost"] < 0) if(!silent) - to_chat(user, "You need [proselytize_values["power_cost"]]W power to proselytize [target]!") - else if(stored_power - proselytize_values["power_cost"] > max_power) + var/atom/A = fabrication_values["new_obj_type"] + if(A) + to_chat(user, "You need [fabrication_values["power_cost"]]W power to fabricate \a [initial(A.name)] from [target]!") + else if(stored_power - fabrication_values["power_cost"] > max_power) if(!silent) - to_chat(user, "Your [name] contains too much power to proselytize [target]!") + var/atom/A = fabrication_values["new_obj_type"] + if(A) + to_chat(user, "Your [name] contains too much power to fabricate \a [initial(A.name)] from [target]!") + else + to_chat(user, "Your [name] contains too much power to consume [target]!") return FALSE return TRUE //The repair check proc. -/obj/item/clockwork/clockwork_proselytizer/proc/proselytizer_repair_checks(list/repair_values, atom/target, mob/user, silent) //Exists entirely to avoid an otherwise unreadable series of checks. +/obj/item/clockwork/replica_fabricator/proc/fabricator_repair_checks(list/repair_values, atom/target, mob/user, silent) //Exists entirely to avoid an otherwise unreadable series of checks. if(!islist(repair_values) || QDELETED(target) || QDELETED(user)) return FALSE if(isliving(target)) //standard checks for if we can affect the target @@ -302,7 +321,7 @@ return FALSE if(repair_values["amount_to_heal"] <= 0) //nothing to heal! return FALSE - repair_values["healing_for_cycle"] = min(repair_values["amount_to_heal"], PROSELYTIZER_REPAIR_PER_TICK) //modify the healing for this cycle + repair_values["healing_for_cycle"] = min(repair_values["amount_to_heal"], FABRICATOR_REPAIR_PER_TICK) //modify the healing for this cycle repair_values["power_required"] = round(repair_values["healing_for_cycle"]*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER) //and get the power cost from that if(!can_use_power(RATVAR_POWER_CHECK) && !can_use_power(repair_values["power_required"])) if(!silent) @@ -312,7 +331,7 @@ return TRUE //The sigil charge check proc. -/obj/item/clockwork/clockwork_proselytizer/proc/sigil_charge_checks(list/charge_values, obj/effect/clockwork/sigil/transmission/sigil, mob/user, silent) +/obj/item/clockwork/replica_fabricator/proc/sigil_charge_checks(list/charge_values, obj/effect/clockwork/sigil/transmission/sigil, mob/user, silent) if(!islist(charge_values) || QDELETED(sigil) || QDELETED(user)) return FALSE if(can_use_power(RATVAR_POWER_CHECK)) diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm index 25bedd79d3..ae54b903b6 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm @@ -105,11 +105,11 @@ descname = "Global Structure Buff" name = "Invoke Nezbere, the Brass Eidolon" desc = "Taps the limitless power of Nezbere, one of Ratvar's four generals. The restless toil of the Eidolon will empower a wide variety of clockwork apparatus for a full minute - notably, \ - clockwork proselytizers will charge very rapidly." + replica fabricators will charge very rapidly." invocations = list("I call upon you, Armorer!!", "Let your machinations reign on this miserable station!!", "Let your power flow through the tools of your master!!") channel_time = 150 consumed_components = list(BELLIGERENT_EYE = 6, VANGUARD_COGWHEEL = 6, GEIS_CAPACITOR = 6, REPLICANT_ALLOY = 10) - usage_tip = "Ocular wardens will become empowered, clockwork proselytizers will require no alloy, tinkerer's daemons will produce twice as quickly, \ + usage_tip = "Ocular wardens will become empowered, tinkerer's daemons will produce twice as quickly, \ and interdiction lenses, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power." tier = SCRIPTURE_REVENANT primary_component = REPLICANT_ALLOY 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 9efb9a8eb2..c6eba3e3c9 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm @@ -33,7 +33,7 @@ /datum/clockwork_scripture/create_object/cogscarab descname = "Constructor Soul Vessel Shell" name = "Cogscarab" - desc = "Creates a small shell fitted for soul vessels. Adding an active soul vessel to it results in a small construct with tools and an inbuilt proselytizer." + desc = "Creates a small shell fitted for soul vessels. Adding an active soul vessel to it results in a small construct with tools and an inbuilt fabricator." invocations = list("Call forth...", "...the workers of Armorer.") channel_time = 60 consumed_components = list(BELLIGERENT_EYE = 2, HIEROPHANT_ANSIBLE = 1) @@ -221,24 +221,24 @@ quickbind_desc = "Creates a Soul Vessel, which can be placed in construct shells and cyborg bodies once filled." -//Clockwork Proselytizer: Creates a clockwork proselytizer, used to convert objects and repair clockwork structures. -/datum/clockwork_scripture/create_object/clockwork_proselytizer - descname = "Converts Objects to Ratvarian" - name = "Clockwork Proselytizer" - desc = "Forms a device that, when used on certain objects, converts them into their Ratvarian equivalents. It requires power to function." +//Replica Fabricator: Creates a replica fabricator, used to convert objects and repair clockwork structures. +/datum/clockwork_scripture/create_object/replica_fabricator + descname = "Replaces Objects with Ratvarian Versions" + name = "Replica Fabricator" + desc = "Forms a device that, when used on certain objects, replaces them with their Ratvarian equivalents. It requires power to function." invocations = list("With this device...", "...his presence shall be made known.") channel_time = 20 consumed_components = list(GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 2) whispered = TRUE - object_path = /obj/item/clockwork/clockwork_proselytizer/preloaded - creator_message = "You form a clockwork proselytizer." - 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." + object_path = /obj/item/clockwork/replica_fabricator/preloaded + creator_message = "You form a replica fabricator." + usage_tip = "Clockwork Walls cause nearby Tinkerer's Caches to generate components passively, making this a vital tool. Clockwork Floors heal toxin damage in Servants standing on them." tier = SCRIPTURE_SCRIPT space_allowed = TRUE primary_component = REPLICANT_ALLOY sort_priority = 7 quickbind = TRUE - quickbind_desc = "Creates a Clockwork Proselytizer, which can convert various objects to Ratvarian variants." + quickbind_desc = "Creates a Replica Fabricator, which can convert various objects to Ratvarian variants." //Function Call: Grants the invoker the ability to call forth a Ratvarian spear that deals significant damage to silicons. diff --git a/code/game/gamemodes/clock_cult/clock_structure.dm b/code/game/gamemodes/clock_cult/clock_structure.dm index 64c7135971..5cbaa701fa 100644 --- a/code/game/gamemodes/clock_cult/clock_structure.dm +++ b/code/game/gamemodes/clock_cult/clock_structure.dm @@ -9,7 +9,7 @@ anchored = 1 density = 1 resistance_flags = FIRE_PROOF | ACID_PROOF - var/can_be_repaired = TRUE //if a proselytizer can repair it + var/can_be_repaired = TRUE //if a fabricator can repair it break_message = "The frog isn't a meme after all!" //The message shown when a structure breaks break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks debris = list(/obj/item/clockwork/alloy_shards/large = 1, \ diff --git a/code/game/gamemodes/clock_cult/clock_structures/clock_shells.dm b/code/game/gamemodes/clock_cult/clock_structures/clock_shells.dm index cfcac3b515..e9f02e9e8c 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/clock_shells.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/clock_shells.dm @@ -34,7 +34,7 @@ /obj/structure/destructible/clockwork/shell/cogscarab name = "cogscarab shell" desc = "A small brass shell with a cube-shaped receptable in its center. It gives off an aura of obsessive perfectionism." - clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt proselytizer." + clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt fabricator." icon_state = "clockdrone_shell" mobtype = /mob/living/simple_animal/drone/cogscarab spawn_message = "'s eyes blink open, glowing bright red." diff --git a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm index 25f151def5..722ff99c25 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm @@ -14,7 +14,7 @@ light_color = "#BE8700" var/atom/prey //Whatever Ratvar is chasing var/clashing = FALSE //If Ratvar is FUCKING FIGHTING WITH NAR-SIE - var/proselytize_range = 10 + var/convert_range = 10 dangerous_possession = TRUE /obj/structure/destructible/clockwork/massive/ratvar/Initialize() @@ -58,10 +58,10 @@ /obj/structure/destructible/clockwork/massive/ratvar/process() if(clashing) //I'm a bit occupied right now, thanks return - for(var/I in circlerangeturfs(src, proselytize_range)) + for(var/I in circlerangeturfs(src, convert_range)) var/turf/T = I T.ratvar_act() - for(var/I in circleviewturfs(src, round(proselytize_range * 0.5))) + for(var/I in circleviewturfs(src, round(convert_range * 0.5))) var/turf/T = I T.ratvar_act(TRUE) var/dir_to_step_in = pick(GLOB.cardinal) diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index d90c42fe4a..31f52a42fc 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -21,15 +21,15 @@ if(has_latches) if(prob(10)) latches = "double_latch" - if(prob(1)) - latches = "triple_latch" + if(prob(1)) + latches = "triple_latch" update_icon() /obj/item/weapon/storage/toolbox/update_icon() ..() cut_overlays() if(has_latches) - add_overlay(latches) + add_overlay(latches) /obj/item/weapon/storage/toolbox/suicide_act(mob/user) @@ -140,10 +140,10 @@ max_combined_w_class = 28 storage_slots = 28 attack_verb = list("robusted", "crushed", "smashed") - var/proselytizer_type = /obj/item/clockwork/clockwork_proselytizer/scarab + var/fabricator_type = /obj/item/clockwork/replica_fabricator/scarab /obj/item/weapon/storage/toolbox/brass/prefilled/PopulateContents() - new proselytizer_type(src) + new fabricator_type(src) new /obj/item/weapon/screwdriver/brass(src) new /obj/item/weapon/wirecutters/brass(src) new /obj/item/weapon/wrench/brass(src) @@ -151,7 +151,7 @@ new /obj/item/weapon/weldingtool/experimental/brass(src) /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar - var/slab_type = /obj/item/clockwork/slab + var/slab_type = /obj/item/clockwork/slab /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/PopulateContents() ..() @@ -159,7 +159,7 @@ /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin slab_type = /obj/item/clockwork/slab/debug - proselytizer_type = /obj/item/clockwork/clockwork_proselytizer/scarab/debug + fabricator_type = /obj/item/clockwork/replica_fabricator/scarab/debug /obj/item/weapon/storage/toolbox/artistic diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 4934636948..c51c543f26 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -84,6 +84,7 @@ new /obj/item/device/flashlight/seclite(src) new /obj/item/weapon/pinpointer(src) new /obj/item/clothing/under/rank/head_of_security/grey(src) + new /obj/item/clothing/under/rank/head_of_security/grey(src) new /obj/item/weapon/storage/lockbox/secmedal(src) /obj/structure/closet/secure_closet/warden diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 64d93e914e..4b912923a2 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -248,6 +248,7 @@ /obj/structure/grille/ratvar icon_state = "ratvargrille" + name = "cog grille" desc = "A strangely-shaped grille." broken_type = /obj/structure/grille/ratvar/broken diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 2f6b03bef1..4b2017fab6 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -50,7 +50,7 @@ deconstruct() /obj/structure/lattice/clockwork - name = "clockwork lattice" + name = "cog lattice" desc = "A lightweight support lattice. These hold the Justicar's station together." icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi' diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 8b6f43ee25..ceb1ca85b5 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -11,7 +11,7 @@ desc = "It's watching you suspiciously." /obj/structure/closet/crate/necropolis/tendril/PopulateContents() - var/loot = rand(1,27) + var/loot = rand(1,28) switch(loot) if(1) new /obj/item/device/shared_storage/red(src) @@ -69,6 +69,8 @@ if(27) new /obj/item/borg/upgrade/modkit/lifesteal(src) new /obj/item/weapon/bedsheet/cult(src) + if(28) + new /obj/item/borg/upgrade/modkit/bounty(src) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 824f5b5f02..f07dca7d32 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -250,7 +250,7 @@ ratvar_modules = list( /obj/item/clockwork/slab/cyborg, /obj/item/clockwork/ratvarian_spear/cyborg, - /obj/item/clockwork/clockwork_proselytizer/cyborg) + /obj/item/clockwork/replica_fabricator/cyborg) moduleselect_icon = "standard" feedback_key = "cyborg_standard" hat_offset = -3 @@ -314,7 +314,7 @@ emag_modules = list(/obj/item/borg/stun) ratvar_modules = list( /obj/item/clockwork/slab/cyborg/engineer, - /obj/item/clockwork/clockwork_proselytizer/cyborg) + /obj/item/clockwork/replica_fabricator/cyborg) cyborg_base_icon = "engineer" moduleselect_icon = "engineer" feedback_key = "cyborg_engineering" @@ -441,7 +441,7 @@ emag_modules = list(/obj/item/weapon/reagent_containers/spray/cyborg_lube) ratvar_modules = list( /obj/item/clockwork/slab/cyborg/janitor, - /obj/item/clockwork/clockwork_proselytizer/cyborg) + /obj/item/clockwork/replica_fabricator/cyborg) cyborg_base_icon = "janitor" moduleselect_icon = "janitor" feedback_key = "cyborg_janitor" diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm index 1c70ca57e5..7399e727bc 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm @@ -91,6 +91,16 @@ icon_living = icon_state icon_dead = "[visualAppearence]_dead" +/obj/item/drone_shell/dusty + name = "derelict drone shell" + desc = "A long-forgotten drone shell. It seems kind of... Space Russian." + drone_type = /mob/living/simple_animal/drone/derelict + +/mob/living/simple_animal/drone/derelict + name = "derelict drone" + default_hatmask = /obj/item/clothing/head/ushanka + + /mob/living/simple_animal/drone/cogscarab name = "cogscarab" desc = "A strange, drone-like machine. It constantly emits the hum of gears." @@ -120,14 +130,14 @@ hacked = TRUE visualAppearence = CLOCKDRONE can_be_held = FALSE - flavortext = "You are a cogscarab, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt proselytizer that can convert brass \ - to liquified alloy, a set of relatively fast tools, can communicate over the Hierophant Network with :b, and are immune to extreme \ + flavortext = "You are a cogscarab, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt fabricator that can convert brass \ + to power, a set of relatively fast tools, can communicate over the Hierophant Network with :b, and are immune to extreme \ temperatures and pressures. \nYour goal is to serve the Justiciar and his servants by repairing and defending all they create." -/mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal proselytizer +/mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal fabricatorlab that it can use and a normal fabricator default_storage = /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar -/mob/living/simple_animal/drone/cogscarab/admin //an admin-only subtype of cogscarab with a no-cost proselytizer and slab in its box +/mob/living/simple_animal/drone/cogscarab/admin //an admin-only subtype of cogscarab with a no-cost fabricator and slab in its box default_storage = /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin /mob/living/simple_animal/drone/cogscarab/Initialize() @@ -191,11 +201,41 @@ /mob/living/simple_animal/drone/cogscarab/ratvar_act() fully_heal(TRUE) -/obj/item/drone_shell/dusty - name = "derelict drone shell" - desc = "A long-forgotten drone shell. It seems kind of... Space Russian." - drone_type = /mob/living/simple_animal/drone/derelict +/mob/living/simple_animal/drone/cogscarab/update_icons() + if(stat != DEAD) + if(incapacitated()) + icon_state = "[visualAppearence]_flipped" + else + icon_state = visualAppearence + else + icon_state = "[visualAppearence]_dead" -/mob/living/simple_animal/drone/derelict - name = "derelict drone" - default_hatmask = /obj/item/clothing/head/ushanka +/mob/living/simple_animal/drone/cogscarab/Stun(amount, updating = 1, ignore_canstun = 0) + . = ..() + if(.) + update_icons() + +/mob/living/simple_animal/drone/cogscarab/SetStunned(amount, updating = 1, ignore_canstun = 0) + . = ..() + if(.) + update_icons() + +/mob/living/simple_animal/drone/cogscarab/AdjustStunned(amount, updating = 1, ignore_canstun = 0) + . = ..() + if(.) + update_icons() + +/mob/living/simple_animal/drone/cogscarab/Weaken(amount, updating = 1, ignore_canweaken = 0) + . = ..() + if(.) + update_icons() + +/mob/living/simple_animal/drone/cogscarab/SetWeakened(amount, updating = 1, ignore_canweaken = 0) + . = ..() + if(.) + update_icons() + +/mob/living/simple_animal/drone/cogscarab/AdjustWeakened(amount, updating = 1, ignore_canweaken = 0) + . = ..() + if(.) + update_icons() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index 99958268a5..a379b0e8ac 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -79,3 +79,6 @@ crusher_loot = /obj/item/crusher_trophy/watcher_wing loot = list() butcher_results = list(/obj/item/weapon/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1) + +/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril + fromtendril = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index 0a5b9957f2..50f3d7260b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -91,6 +91,10 @@ stat_attack = UNCONSCIOUS robust_searching = 1 +/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril + fromtendril = TRUE + + //tentacles /obj/effect/goliath_tentacle name = "Goliath tentacle" diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index b7ecba8431..4bbfb9ab72 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -124,6 +124,10 @@ new /obj/effect/mob_spawn/human/corpse/damaged(T) ..(gibbed) +/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril + fromtendril = TRUE + + //Legion skull /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion name = "legion" diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index f9e458cfd8..57e04b1331 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -16,6 +16,7 @@ a_intent = INTENT_HARM var/throw_message = "bounces off of" var/icon_aggro = null // for swapping to when we get aggressive + var/fromtendril = FALSE see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE mob_size = MOB_SIZE_LARGE diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm index 1ef8dd9f13..02257193ff 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm @@ -17,7 +17,7 @@ maxHealth = 250 max_mobs = 3 spawn_time = 300 //30 seconds default - mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk/watcher + mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril spawn_text = "emerges from" atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 @@ -28,10 +28,10 @@ var/obj/effect/light_emitter/tendril/emitted_light /mob/living/simple_animal/hostile/spawner/lavaland/goliath - mob_type = /mob/living/simple_animal/hostile/asteroid/goliath/beast + mob_type = /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril /mob/living/simple_animal/hostile/spawner/lavaland/legion - mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord/legion + mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril /mob/living/simple_animal/hostile/spawner/lavaland/Initialize() . = ..() diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 62bc464ac1..2cb9bf0b11 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -163,6 +163,7 @@ range = 3 log_override = TRUE + var/pressure_decrease_active = FALSE var/pressure_decrease = 0.25 var/obj/item/weapon/gun/energy/kinetic_accelerator/kinetic_gun @@ -179,6 +180,7 @@ if(pressure > 50) name = "weakened [name]" damage = damage * pressure_decrease + pressure_decrease_active = TRUE . = ..() /obj/item/projectile/kinetic/on_range() @@ -194,7 +196,10 @@ if(!target_turf) target_turf = get_turf(src) if(kinetic_gun) //hopefully whoever shot this was not very, very unfortunate. - for(var/obj/item/borg/upgrade/modkit/M in kinetic_gun.get_modkits()) + var/list/mods = kinetic_gun.get_modkits() + for(var/obj/item/borg/upgrade/modkit/M in mods) + M.projectile_strike_predamage(src, target_turf, target, kinetic_gun) + for(var/obj/item/borg/upgrade/modkit/M in mods) M.projectile_strike(src, target_turf, target, kinetic_gun) if(ismineralturf(target_turf)) var/turf/closed/mineral/M = target_turf @@ -265,6 +270,10 @@ /obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/item/projectile/kinetic/K) +//use this one for effects you want to trigger before mods that do damage +/obj/item/borg/upgrade/modkit/proc/projectile_strike_predamage(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA) +//and this one for things that don't need to trigger before other damage-dealing mods + /obj/item/borg/upgrade/modkit/proc/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA) //Range @@ -393,7 +402,7 @@ modifier = -14 //Makes the cooldown 3 seconds(with no cooldown mods) if you miss. Don't miss. cost = 50 -/obj/item/borg/upgrade/modkit/cooldown/repeater/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA) +/obj/item/borg/upgrade/modkit/cooldown/repeater/projectile_strike_predamage(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA) var/valid_repeat = FALSE if(isliving(target)) var/mob/living/L = target @@ -403,7 +412,7 @@ valid_repeat = TRUE if(valid_repeat) KA.overheat = FALSE - KA.attempt_reload(KA.overheat_time * 0.25) //If you hit, the cooldown drops to 0.75 seconds. + KA.attempt_reload(KA.overheat_time * 0.25) //If you hit, the cooldown drops to 0.75 seconds. /obj/item/borg/upgrade/modkit/lifesteal name = "lifesteal crystal" @@ -414,7 +423,7 @@ cost = 20 var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) -/obj/item/borg/upgrade/modkit/lifesteal/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA) +/obj/item/borg/upgrade/modkit/lifesteal/projectile_strike_predamage(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA) if(isliving(target) && isliving(K.firer)) var/mob/living/L = target if(L.stat == DEAD) @@ -438,6 +447,43 @@ return new /obj/effect/temp_visual/resonance(target_turf, K.firer, null, 30) +/obj/item/borg/upgrade/modkit/bounty + name = "death syphon" + desc = "Killing or assisting in killing a creature permenantly increases your damage against that type of creature." + denied_type = /obj/item/borg/upgrade/modkit/bounty + modifier = 1.25 + cost = 30 + var/maximum_bounty = 25 + var/list/bounties_reaped = list() + +/obj/item/borg/upgrade/modkit/bounty/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA) + if(isliving(target)) + var/mob/living/L = target + var/list/existing_marks = L.has_status_effect_list(STATUS_EFFECT_SYPHONMARK) + for(var/i in existing_marks) + var/datum/status_effect/syphon_mark/SM = i + if(SM.reward_target == src) //we want to allow multiple people with bounty modkits to use them, but we need to replace our own marks so we don't multi-reward + SM.reward_target = null + qdel(SM) + var/datum/status_effect/syphon_mark/SM = L.apply_status_effect(STATUS_EFFECT_SYPHONMARK) + SM.reward_target = src + if(bounties_reaped[L.type]) + var/kill_modifier = 1 + if(K.pressure_decrease_active) + kill_modifier *= K.pressure_decrease + var/armor = L.run_armor_check(K.def_zone, K.flag, "", "", K.armour_penetration) + L.apply_damage(bounties_reaped[L.type]*kill_modifier, K.damage_type, K.def_zone, armor) + +/obj/item/borg/upgrade/modkit/bounty/proc/get_kill(mob/living/L) + var/bonus_mod = 1 + if(ismegafauna(L)) //megafauna reward + bonus_mod = 4 + if(!bounties_reaped[L.type]) + bounties_reaped[L.type] = min(modifier * bonus_mod, maximum_bounty) + else + bounties_reaped[L.type] = min(bounties_reaped[L.type] + (modifier * bonus_mod), maximum_bounty) + + //Indoors /obj/item/borg/upgrade/modkit/indoors name = "decrease pressure penalty" diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index c8fc98d4f5018967096dbbb9e5c597cfa3722b77..214bfd744ea9286559443600a5ef9a291bf2a724 100644 GIT binary patch delta 1004 zcmVkHuP3y>rMPmv`nHiA6VE$|$qM}ec^%+O1T6H3~R^Vj#Vj(6;MRx}&^ZOqkKK|9byZU&Mh9U<~9rjQ-|8$YBlm=3CbyNO8lSu(X0WXt{ z0jL7M6q7dsCIL5-UIHTlSCfJQ?g2NGaRZ3~U6cC*D}NoCX+Xs#?8_e%-4p+(bmR%R z`AkXbd-)mSP(T-kP`~a4ot->wf@_SKBJwY(c`IR336_Tc1Jcs=zFv}9+l)_8Vx~AW zpGd*r_W#9+$uDon^WEVS#WgDGFR6J8eq2ytw!qUDXR8C>J?DQED38tcgg%33tjESR z4aAM~&3`9_mg2`wY-@yb^H~g2>3@4GzwzGaTxMifine!{@;1@zE$bO_H0-=JaB9dhz6ua|OCyZX*t{2o%V>U4LO| zSbwb08_cbUrDZaWC;}#f&;(ww>lrNNd;sPz1r7If8_|qkouYqUb9zVD_XoyXhsl=b zXiw1LSITaZl#EGX5biL#4GA0W?ZDwLjP1FA( zWdgr;J=YKT8N3xSMD~mTNLvNNMau-_{0J#6HXRSKx|m{SCE5Ave09D$e@HnBOMfp~ zABRjpb&Sdl`fM5B@1ga_8+)wb)dnexU%P~CxtiQk>||?2w}rTK{nEpM2j%bSYW981 zA{W(poV`9E57jmlX$u+Ncx{9{I_cdYb#NZhWrb=e+llrzC15vz;b`b2 zPz1~C3UUl7yEIy!6ahIehI>08BV0pCaJwpJ)M6fSQZ{U7AFmspkHxQ3y>rMP?04oHiHy(`|up3M}ec^%+O1T6H3~R^Vh$_I^MD4So^XqT#Km66ayZUgEh9U+Tj1%7v(%c)vG=EpA^^FHHXiF)8nI2a+)MJm(A(L>h$8tW9JHVz1&J1Vi72ice@_L z(tosAp*NUY5lh=-8dC&J2B8VOV%IZRO8NlIp9>o9>NcVozc@wzyax4-uI~?wxDJyo z&(fZt!!MNGBq4uuj45Mm05tlTz`r#4-s7psxX-Dq%-=_wQMo+3~U*=?!s~c zzjl*sZ9~C~hA!%xB4!;@q3k9w^cyq$h#b(Gd{Uw8(kO=dZf2I0p(S3fL7o<4YMlNb zDHHg$>$!fw&)}_yA+l!#K-wx8E?Xub=SN6svGI6_)x{JuE6L7R=d1J8`9sQ4Sbuua z`bcB~s$*1c&}YjCe-Euc;MijgFE>b8{MsdC%k|`zVkcWGx-G<=>z5u6JScxpSF`V9 z7P+X-f2|=q&a^q?vY28qhxQi)j>Op9ktIV?;?3XhA#J0K zBim_{!f+4=L#2X ze1L%2Hv8bfq3E!~56guj=d*2AEEhWmEuOyrv{Vj33F<&4OxMeWLJh}kf14F-kF6e~O)hxc?2gLGWB(@6^|=~=NrcJ4J#SXH|+e(^9`#mf1Y^0Ve7#!<;7Ex z4=oDD^UZapR?2-xm}rMF(f6Q#=pIy=*ukqK3CW^gy=y=5P8JT}2#oL@!gO6*x!2%C z4^E*uTUU{Fc@DN_>x8S=o8F<3O{{YQrQodKQNz__RJzs1bwK6~9Xc;0$R=SQ^}`}B z*~py)zM4#e6PbWce~}Di&Ajp)cnC5e1050xJ;e)j&92Cc{$cY z{!D+mpgpl{Q`z34tu@F0MCZsS)Q#3sxn>0`*(#wo7=kgie@h;BIi5e=<>T{k%!!!X zAYkNlgM6_Yn1IH>bkqDfL=K0abDLCvtu;3^?32SS}NYb>L1EB-54Np0m@Z{3^NX*=VHc((6BPah_F z&|1`UX4E++!uLFsvj&B4a0V05+8%{(z^T;q79DKYoRy5{Ppsms$g61`J2GUA&{iha zWPHMEz$xKd&^mQ2{2eM0eEC@T)x+RhRJ3m&r_KrgIC1i5a5X-Tz6Mw0BiPpnPP|f> x{=4FbWs1enGPPQUmer(X%HU)6<=b=i{Pkt|KMs2c)KVh+@`L;XxBLSEOwwgI^t%86 delta 981 zcmV;`11kK&tOv-f2aqHI&ygh{f7Os3XWATcSxm8*L;DK?N8;G*$dVx`@n*lihqR3{ zj%=q*3d2DhkdKegB1PqW_Rr^kpT1^~U!InGbe^oqwpo?)<)SAQnrxe`%H^U#s+(|p z@Bsp5+w7eKhoZv{-z^u4oX@sdv0S`3Xz}>{m!)zDN>B$XVY*%}6lyqRf7`5JBi9M? z+fI=r&^H6zgQ<7mZpTpCwsW>6pVH@g$QsGtE@7*~&A^^fYpT(q2?7s^jH?0cP<|n8 z-8YDd7yI!9QS!7%LP7_Uf^~@uKc#S{5`6)!(FkyD5<998>@-O*L4elwkg$()TC;-j ze8o!6c>Zykj&H#?s00{le^Im zyja7ZzYU93?8#dvcuKfMV}tK($hKLrW<@oEQA~;-+zvg}O%NJQs%%c?y#or3@Eyu& zV{dm_?9uzwI=yWB!6P`?kf|?wt$17^Jl`;$Z&=BAzG0_lo^M!nfA+-l4ODbJpY zd}vWHo^LKQwNman!bCfaiM|E>OLx?0wUw{Eb+4jx)}uZI`X3X;xq8!r;@vFl!4VkY zJA~=lwsNPzi5{FnbF!`?>+%$A&DIH5u`|6xBb!+31WLhK!K0?D$*6R@jcb9-D>`&u zNRUm!KI(}@Ub2xpe+hgsnFJ>?0i7Zl$eMX2I`9x=KnB_;5_*Ui>6%@*mkWnI88sEh zp=`j_sjN1WfzE=C1R6`HN=6w&ROCmw7yK&nQ{k>y02+-KHMYs!;L^Kk(I_&tXl-(H zUquyDa#rN!SReU2J?f11#Ij9gdyTf%9R3rXBcD(=T1(}ce-*4`tAyTQ2*%VddEDiA z{&16zPs33sVseFmk<%6O#cp5%8Uxc!^Vc9b9Dq)3QUSKsT+y(P4%d+XF?9yAMsym& zjO{_pn%~o#XAm>z_c4e$gZr5OtZ91;VD11sN&<|st&q0utVxdIzj4Aku83OOK2e8n zS?__lvNME#_aZEhf z_n@Z_6g_Ay>Nzv&oKxXj9?DsR!Z$dB321E(!Z+YlYI=(fw`