mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-05 14:32:52 +00:00
## About The Pull Request Reworks most of the Void Heretic kit. All Void spells now apply a stacking debuff that makes you gradually colder. Void Blast has been replaced with a new spell "Void Conduit" and a new Side knowledge spell, "Void Prison" has been introduced. Waltz At The End Of Time has been completely overhauled. Lastly Void Blade has been resprited along with the overlay of Void Chill, check any of the linked videos to see the new look. All new sprites have been kindly made by OrcaCora. ## Why It's Good For The Game Void path is *Supposedly* themed around the cold of space but doesn't have any tools to live up to the fantasy of being an harbringer of the Void whose main goal is to freeze the station to an icicle. Then there's also the issue of Void being utterly underwhelming compared to his neighbors, Cold is way too easy to treat as a status effect, so much so, a simple cup of coffee can utterly shutdown the void storm, which is just unacceptable. # **Changes** - **Void Chill**: Is now a stacking debuff, each stack slows movement speed by a percentage while lowering body temperature, upon reaching the cap, which is 5 stacks, the victim cannot heat up anymore, all void Spells apply 1 stack of the debuff, with the exception of the grasp applying 5 (2 for the mark and 3 for the detonation) and the blade upgrade applying 2. **Reasoning**: Void chill currently suffers from being completely shutdown by sipping tea, coffee or having the COLD_RESIST trait,with this change you can still negate the damage and the slowdown you get from being cold but not the slowdown from the debuff itself. - **Aristocrat's Way**: Now grants no slip on ice and water tiles on cold or depressurized turfs **Reasoning:** Since the rework revolves around making Void heretic more involved in freezing the station, they should be able to move in their domain without getting punished for it. - **Void Cloak:** Can now be toggled on and off to make the cloak visible or invisible; when the cloak is visible it grants low pressure immunity trait. **Reasoning:** Not having pressure resistance as a Void Heretic just sucks, as you are clearly intended to somewhat go into space at some point; giving it to the cloak is a good compromise since you sacrifice better protection (***the armor values of the cloak are pitiful***) for utility. - **Replaces "Void Blast" with a new spell, "Void Conduit"**. **Void Conduit:** Opens a gate to the Void; it releases an intermittent pulse that damages windows and airlocks and applies a stack of void chill to non heretics, Heretics are granted the low pressure resistance trait. **Reasoning**: I like the idea behind Void Blast; unfortunately, the spell has limited uses if an area isn't already spaced, which is hard to do considering the current kit of Void Heretic doesn't provide anything to help in that regard. I wanted to give Void Heretic a tool to turn any area of their choosing into their ideal habitat. Not amazing for quick assassinations, good if you are anticipating a fight or want to simply expand your domain, the added Trait might seem redundant, but let's not forget that the void cloak is still a side knowledge, I don't want newbie heretics to space an area and accidentally killing themselves because of it. Video Demonstration: https://www.youtube.com/watch?v=nhPdj1hIgSI - **New side knowledge: "Void Prison."** **Void Prison:** It makes the target invulnerable and unable to do anything for 10 seconds , when the spell ends, it applies a few stacks of void chill, cannot be self-cast. It occupies the same slot of Blood Siphon (inbetween Raw Ritual and Void Phase.) Video Demonstration: https://www.youtube.com/watch?v=nKZd8aEcZFw **Reasoning**: Void is technically meant to be an assassination path and not really apt at tackling multiple opponents, this spell might come into clutch if you are outnumbered, or simply want some breathing room from your pursuers. - **Void Jaunt and Void Pull** Cooldown respectively reduced to 25 and 30 seconds, down from 30 and 40. **Reasoning:** I felt that the cooldown on these was a bit too high overall; as it stands, Void Phase cooldown is twice as long as Ashen passage, one of the best and arguably most sidepathed spells in the game. Granted phase is faster and has more range but I don't think it justifies its cooldown being this long. Void pull could also use slightly less cooldown, being the very last spell you unlock and offering a simple melee knockdown. - **Seeking Blade:** Now applies 2 stacks of void chill per hit. **Reasoning:** Seeking blade is a bit underwhelming for being the final blade upgrade, teleporting to a target you just stunned at melee range is incredibly niche, now that Void chill is a stacking debuff we can probably just slap it on the blade itself. - **Waltz At The End Of Time:** The Heretic becomes weightless and able to levitate around, (carp movement essentialy). The heavy storm is no longer bound to the room the heretic is in but is now an aura around them, this does a few things. 1) Releases a pulse that depressurizes areas, shatters windows, airlocks and firelocks, and applies a stack of void chill to non heretics, the passive burn and oxy damage effect has been removed. 2) Grants to the Heretic projectile deflection. **Reasoning:** Void Has the reputation of having the weakest ascension in the game, which it's hard to disagree on considering you can completely neutralize the effects of the storm by simply sipping tea and how generally little it does overall. It's also kind of strange that you have this massive Eldritch storm ravaging the station and for it to have no effects on its atmosphere, infrastructure, or projectiles whatsoever. Video Demonstration: https://www.youtube.com/watch?v=1_blr20-hgA ## Changelog 🆑 add: New Heretic Side Knowledge, Void Prison. add: New Void Spell Void Conduit has now replaced Void Blast. balance: Void Chill is now a stacking debuff, upon reaching the cap, makes the target unable to heat up. balance: Aristocrat's way now grants immunity to ice and water slips on cold turfs. balance: Void Cloak now grants low pressure resistance when visible. balance: Void Phase and Void pull have received a minor CD reduction. balance: Seeking Blade now applies a couple of stacks of void chill. balance: Void Heretic Ascension has been overhauled, it's now protects the heretic from projectiles, destroys windows and airlocks and applies void chills to non heretics. image: Void Blade and Void Chill have received some new sprites. /🆑 --------- Co-authored-by: Xander3359 <66163761+Xander3359@users.noreply.github.com> Co-authored-by: necromanceranne <40847847+necromanceranne@users.noreply.github.com>
218 lines
8.0 KiB
Plaintext
218 lines
8.0 KiB
Plaintext
/**
|
|
* Component which allows clothing to deploy a different kind of clothing onto you.
|
|
* The simplest example is hooded suits deploying hoods onto your head.
|
|
*/
|
|
/datum/component/toggle_attached_clothing
|
|
/// Instance of the item we're creating
|
|
var/obj/item/deployable
|
|
/// Action used to toggle deployment
|
|
var/datum/action/item_action/toggle_action
|
|
/// Typepath of what we're creating
|
|
var/deployable_type
|
|
/// Which slot this item equips into
|
|
var/equipped_slot
|
|
/// Name of toggle action
|
|
var/action_name = ""
|
|
/// If true, we delete our deployable on toggle rather than putting it in nullspace
|
|
var/destroy_on_removal
|
|
/// Current state of our deployable equipment
|
|
var/currently_deployed = FALSE
|
|
/// What should be added to the end of the parent icon state when equipment is deployed? Set to "" for no change
|
|
var/parent_icon_state_suffix = ""
|
|
/// Icon state for overlay to display over the parent item while deployable item is not deployed
|
|
var/down_overlay_state_suffix = ""
|
|
/// Overlay to display over the parent item while deployable item is not deployed
|
|
var/mutable_appearance/undeployed_overlay
|
|
/// Optional callback triggered before deploying, return TRUE to continue or FALSE to cancel
|
|
var/datum/callback/pre_creation_check
|
|
/// Optional callback triggered when we create our deployable equipment
|
|
var/datum/callback/on_created
|
|
/// Optional callback triggered when we have deployed our equipment
|
|
var/datum/callback/on_deployed
|
|
/// Optional callback triggered before we hide our equipment, before as we may delete it afterwards
|
|
var/datum/callback/on_removed
|
|
|
|
/datum/component/toggle_attached_clothing/Initialize(
|
|
deployable_type,
|
|
equipped_slot,
|
|
action_name = "Toggle",
|
|
destroy_on_removal = FALSE,
|
|
parent_icon_state_suffix = "",
|
|
down_overlay_state_suffix = "",
|
|
datum/callback/pre_creation_check,
|
|
datum/callback/on_created,
|
|
datum/callback/on_deployed,
|
|
datum/callback/on_removed,
|
|
)
|
|
. = ..()
|
|
if (!isitem(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
if (!deployable_type || !equipped_slot)
|
|
return COMPONENT_INCOMPATIBLE // Not strictly true but INITIALIZE_HINT_QDEL doesn't work from components
|
|
src.deployable_type = deployable_type
|
|
src.equipped_slot = equipped_slot
|
|
src.destroy_on_removal = destroy_on_removal
|
|
src.parent_icon_state_suffix = parent_icon_state_suffix
|
|
src.down_overlay_state_suffix = down_overlay_state_suffix
|
|
src.pre_creation_check = pre_creation_check
|
|
src.on_created = on_created
|
|
src.on_deployed = on_deployed
|
|
src.on_removed = on_removed
|
|
|
|
var/obj/item/clothing_parent = parent
|
|
toggle_action = new(parent)
|
|
toggle_action.name = action_name
|
|
clothing_parent.add_item_action(toggle_action)
|
|
|
|
RegisterSignal(parent, COMSIG_ITEM_UI_ACTION_CLICK, PROC_REF(on_toggle_pressed))
|
|
RegisterSignal(parent, COMSIG_ITEM_UI_ACTION_SLOT_CHECKED, PROC_REF(on_action_slot_checked))
|
|
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_parent_equipped))
|
|
RegisterSignal(parent, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(remove_deployable))
|
|
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED_AS_OUTFIT, PROC_REF(on_parent_equipped_outfit))
|
|
if (down_overlay_state_suffix)
|
|
var/overlay_state = "[initial(clothing_parent.icon_state)][down_overlay_state_suffix]"
|
|
undeployed_overlay = mutable_appearance(initial(clothing_parent.worn_icon), overlay_state, -SUIT_LAYER)
|
|
RegisterSignal(parent, COMSIG_ITEM_GET_WORN_OVERLAYS, PROC_REF(on_checked_overlays))
|
|
clothing_parent.update_slot_icon()
|
|
|
|
if (!destroy_on_removal)
|
|
create_deployable()
|
|
|
|
/datum/component/toggle_attached_clothing/Destroy(force)
|
|
unequip_deployable()
|
|
QDEL_NULL(deployable)
|
|
QDEL_NULL(toggle_action)
|
|
undeployed_overlay = null
|
|
pre_creation_check = null
|
|
on_created = null
|
|
on_deployed = null
|
|
on_removed = null
|
|
return ..()
|
|
|
|
/// Toggle deployable when the UI button is clicked
|
|
/datum/component/toggle_attached_clothing/proc/on_toggle_pressed(obj/item/source, mob/user, datum/action)
|
|
SIGNAL_HANDLER
|
|
if (action != toggle_action)
|
|
return
|
|
toggle_deployable()
|
|
return COMPONENT_ACTION_HANDLED
|
|
|
|
/// Called when action attempts to check what slot the item is worn in
|
|
/datum/component/toggle_attached_clothing/proc/on_action_slot_checked(obj/item/clothing/source, mob/user, datum/action, slot)
|
|
SIGNAL_HANDLER
|
|
if (action != toggle_action)
|
|
return
|
|
if (!(source.slot_flags & slot))
|
|
return COMPONENT_ITEM_ACTION_SLOT_INVALID
|
|
|
|
/// Apply an overlay while the item is not deployed
|
|
/datum/component/toggle_attached_clothing/proc/on_checked_overlays(obj/item/source, list/overlays, mutable_appearance/standing, isinhands, icon_file)
|
|
SIGNAL_HANDLER
|
|
if (isinhands || currently_deployed)
|
|
return
|
|
overlays += undeployed_overlay
|
|
|
|
/// Deploys gear if it is hidden, hides it if it is deployed
|
|
/datum/component/toggle_attached_clothing/proc/toggle_deployable()
|
|
if (currently_deployed)
|
|
remove_deployable()
|
|
return
|
|
|
|
var/obj/item/parent_gear = parent
|
|
if (!ishuman(parent_gear.loc))
|
|
return
|
|
var/mob/living/carbon/human/wearer = parent_gear.loc
|
|
if (wearer.is_holding(parent_gear))
|
|
parent_gear.balloon_alert(wearer, "wear it first!")
|
|
return
|
|
if (wearer.get_item_by_slot(equipped_slot))
|
|
parent_gear.balloon_alert(wearer, "slot occupied!")
|
|
return
|
|
if (!deployable && !create_deployable())
|
|
return
|
|
if (!wearer.equip_to_slot_if_possible(deployable, slot = equipped_slot))
|
|
if(destroy_on_removal)
|
|
remove_deployable()
|
|
return
|
|
currently_deployed = TRUE
|
|
on_deployed?.Invoke(deployable)
|
|
if (parent_icon_state_suffix)
|
|
parent_gear.icon_state = "[initial(parent_gear.icon_state)][parent_icon_state_suffix]"
|
|
parent_gear.worn_icon_state = parent_gear.icon_state
|
|
parent_gear.update_slot_icon()
|
|
wearer.update_mob_action_buttons()
|
|
|
|
/// Undeploy gear if it moves slots somehow
|
|
/datum/component/toggle_attached_clothing/proc/on_parent_equipped(obj/item/clothing/source, mob/equipper, slot)
|
|
SIGNAL_HANDLER
|
|
if (slot & equipped_slot)
|
|
return
|
|
remove_deployable()
|
|
|
|
/// Display deployed if worn in an outfit
|
|
/datum/component/toggle_attached_clothing/proc/on_parent_equipped_outfit(obj/item/clothing/source, mob/equipper, visuals_only, slot)
|
|
SIGNAL_HANDLER
|
|
create_deployable()
|
|
toggle_deployable()
|
|
|
|
/// Create our gear, returns true if we actually made anything
|
|
/datum/component/toggle_attached_clothing/proc/create_deployable()
|
|
if (deployable)
|
|
return FALSE
|
|
if (pre_creation_check && !pre_creation_check.Invoke())
|
|
return FALSE
|
|
deployable = new deployable_type(parent)
|
|
if (!istype(deployable))
|
|
stack_trace("Tried to create non-clothing item from toggled clothing.")
|
|
RegisterSignal(deployable, COMSIG_ITEM_DROPPED, PROC_REF(on_deployed_dropped))
|
|
RegisterSignal(deployable, COMSIG_ITEM_EQUIPPED, PROC_REF(on_deployed_equipped))
|
|
RegisterSignal(deployable, COMSIG_QDELETING, PROC_REF(on_deployed_destroyed))
|
|
on_created?.Invoke(deployable)
|
|
return TRUE
|
|
|
|
/// Undeploy gear if you drop it
|
|
/datum/component/toggle_attached_clothing/proc/on_deployed_dropped()
|
|
SIGNAL_HANDLER
|
|
remove_deployable()
|
|
|
|
/// Undeploy gear if it moves slots somehow
|
|
/datum/component/toggle_attached_clothing/proc/on_deployed_equipped(obj/item/clothing/source, mob/equipper, slot)
|
|
SIGNAL_HANDLER
|
|
if (source.slot_flags & slot)
|
|
return
|
|
remove_deployable()
|
|
|
|
/// Undeploy gear if it is deleted
|
|
/datum/component/toggle_attached_clothing/proc/on_deployed_destroyed()
|
|
SIGNAL_HANDLER
|
|
remove_deployable()
|
|
deployable = null
|
|
|
|
/// Removes our deployed equipment from the wearer
|
|
/datum/component/toggle_attached_clothing/proc/remove_deployable()
|
|
SIGNAL_HANDLER
|
|
unequip_deployable()
|
|
if (!currently_deployed)
|
|
return
|
|
currently_deployed = FALSE
|
|
on_removed?.Invoke(deployable)
|
|
|
|
var/obj/item/parent_gear = parent
|
|
if(destroy_on_removal)
|
|
QDEL_NULL(deployable)
|
|
if(parent_icon_state_suffix)
|
|
parent_gear.icon_state = "[initial(parent_gear.icon_state)]"
|
|
parent_gear.worn_icon_state = parent_gear.icon_state
|
|
parent_gear.update_slot_icon()
|
|
parent_gear.update_item_action_buttons()
|
|
|
|
/// Removes an equipped deployable atom upon its retraction or destruction
|
|
/datum/component/toggle_attached_clothing/proc/unequip_deployable()
|
|
if (!deployable)
|
|
return
|
|
if (!ishuman(deployable.loc))
|
|
deployable.forceMove(parent)
|
|
return
|
|
var/mob/living/carbon/human/wearer = deployable.loc
|
|
wearer.transferItemToLoc(deployable, parent, force = TRUE, silent = TRUE)
|