diff --git a/code/datums/action.dm b/code/datums/action.dm
index a65294fa40..cf1046ca8f 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -591,3 +591,50 @@
var/mob/M = owner
var/datum/language_holder/H = M.get_language_holder()
H.open_language_menu(usr)
+
+/datum/action/innate/dash
+ name = "Dash"
+ desc = "Teleport to the targeted location."
+ icon_icon = 'icons/mob/actions/actions_items.dmi'
+ button_icon_state = "jetboot"
+ var/charged = TRUE
+ var/charge_rate = 250
+ var/mob/living/carbon/human/holder
+ var/obj/item/dashing_item
+ var/dash_sound = 'sound/magic/blink.ogg'
+ var/recharge_sound = 'sound/magic/charge.ogg'
+ var/beam_effect = "blur"
+ var/phasein = /obj/effect/temp_visual/dir_setting/ninja/phase
+ var/phaseout = /obj/effect/temp_visual/dir_setting/ninja/phase/out
+
+/datum/action/innate/dash/Grant(mob/user, obj/dasher)
+ . = ..()
+ dashing_item = dasher
+ holder = user
+
+/datum/action/innate/dash/IsAvailable()
+ if(charged)
+ return TRUE
+ else
+ return FALSE
+
+/datum/action/innate/dash/Activate()
+ dashing_item.attack_self(holder) //Used to toggle dash behavior in the dashing item
+
+/datum/action/innate/dash/proc/Teleport(mob/user, atom/target)
+ var/turf/T = get_turf(target)
+ if(target in view(user.client.view, get_turf(user)))
+ var/obj/spot1 = new phaseout(get_turf(user), user.dir)
+ user.forceMove(T)
+ playsound(T, dash_sound, 25, 1)
+ var/obj/spot2 = new phasein(get_turf(user), user.dir)
+ spot1.Beam(spot2,beam_effect,time=20)
+ charged = FALSE
+ holder.update_action_buttons_icon()
+ addtimer(CALLBACK(src, .proc/charge), charge_rate)
+
+/datum/action/innate/dash/proc/charge()
+ charged = TRUE
+ holder.update_action_buttons_icon()
+ playsound(dashing_item, recharge_sound, 50, 1)
+ to_chat(holder, "[dashing_item] is ready for another jaunt.")
\ No newline at end of file
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index 25b04b4312..20d218f767 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -384,3 +384,31 @@
if(islist(owner.stun_absorption) && owner.stun_absorption["blooddrunk"])
owner.stun_absorption -= "blooddrunk"
+/datum/status_effect/sword_spin
+ id = "Bastard Sword Spin"
+ duration = 50
+ tick_interval = 8
+ alert_type = null
+
+
+/datum/status_effect/sword_spin/on_apply()
+ owner.visible_message("[owner] begins swinging the sword with inhuman strength!")
+ var/oldcolor = owner.color
+ owner.color = "#ff0000"
+ owner.add_stun_absorption("bloody bastard sword", duration, 2, "doesn't even flinch as the sword's power courses through them!", "You shrug off the stun!", " glowing with a blazing red aura!")
+ owner.spin(duration,1)
+ animate(owner, color = oldcolor, time = duration, easing = EASE_IN)
+ addtimer(CALLBACK(owner, /atom/proc/update_atom_colour), duration)
+ playsound(owner, 'sound/weapons/fwoosh.wav', 75, 0)
+ return ..()
+
+
+/datum/status_effect/sword_spin/tick()
+ playsound(owner, 'sound/weapons/fwoosh.wav', 75, 0)
+ var/obj/item/slashy
+ slashy = owner.get_active_held_item()
+ for(var/mob/living/M in orange(1,owner))
+ slashy.attack(M, owner)
+
+/datum/status_effect/sword_spin/on_remove()
+ owner.visible_message("[owner]'s inhuman strength dissipates and the sword's runes grow cold!")
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 55f8ece5e6..876cace14d 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -72,6 +72,170 @@
if(is_servant_of_ratvar(C) && C.reagents)
C.reagents.add_reagent("heparin", 1)
+/obj/item/twohanded/required/cult_bastard
+ name = "bloody bastard sword"
+ desc = "An enormous sword used by Nar-Sien cultists to rapidly harvest the souls of non-believers."
+ w_class = WEIGHT_CLASS_HUGE
+ block_chance = 50
+ throwforce = 20
+ force = 35
+ armour_penetration = 45
+ throw_speed = 1
+ throw_range = 3
+ sharpness = IS_SHARP
+ light_color = "#ff0000"
+ attack_verb = list("cleaved", "slashed", "torn", "hacked", "ripped", "diced", "carved")
+ icon_state = "cultbastard"
+ item_state = "cultbastard"
+ hitsound = 'sound/weapons/bladeslice.ogg'
+ lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
+ inhand_x_dimension = 64
+ inhand_y_dimension = 64
+ actions_types = list()
+ flags_2 = SLOWS_WHILE_IN_HAND_2
+ var/datum/action/innate/dash/cult/jaunt
+ var/datum/action/innate/cult/spin2win/linked_action
+ var/spinning = FALSE
+ var/spin_cooldown = 250
+ var/list/shards = list()
+ var/dash_toggled = TRUE
+
+/obj/item/twohanded/required/cult_bastard/Initialize()
+ . = ..()
+ set_light(4)
+ jaunt = new(src)
+ linked_action = new(src)
+
+/obj/item/twohanded/required/cult_bastard/can_be_pulled(user)
+ return FALSE
+
+/obj/item/twohanded/required/cult_bastard/attack_self(mob/user)
+ dash_toggled = !dash_toggled
+ if(dash_toggled)
+ to_chat(loc, "You raise the [src] and prepare to jaunt with it.")
+ else
+ to_chat(loc, "You lower the [src] and prepare to swing it normally.")
+
+/obj/item/twohanded/required/cult_bastard/pickup(mob/living/user)
+ . = ..()
+ if(!iscultist(user))
+ if(!is_servant_of_ratvar(user))
+ to_chat(user, "\"I wouldn't advise that.\"")
+ to_chat(user, "An overwhelming sense of nausea overpowers you!")
+ user.Dizzy(80)
+ user.Knockdown(30)
+ return
+ else
+ to_chat(user, "\"One of Ratvar's toys is trying to play with things [user.p_they()] shouldn't. Cute.\"")
+ to_chat(user, "A horrible force yanks at your arm!")
+ user.emote("scream")
+ user.apply_damage(30, BRUTE, pick("l_arm", "r_arm"))
+ user.Knockdown(50)
+ return
+ jaunt.Grant(user, src)
+ linked_action.Grant(user, src)
+ user.update_icons()
+
+/obj/item/twohanded/required/cult_bastard/dropped(mob/user)
+ . = ..()
+ linked_action.Remove(user)
+ jaunt.Remove(user)
+ user.update_icons()
+
+/obj/item/twohanded/required/cult_bastard/IsReflect()
+ if(spinning)
+ playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
+ return TRUE
+ else
+ ..()
+
+/obj/item/twohanded/required/cult_bastard/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(prob(final_block_chance))
+ if(attack_type == PROJECTILE_ATTACK)
+ owner.visible_message("[owner] deflects [attack_text] with [src]!")
+ playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 100, 1)
+ return TRUE
+ else
+ playsound(src, 'sound/weapons/parry.ogg', 75, 1)
+ owner.visible_message("[owner] parries [attack_text] with [src]!")
+ return TRUE
+ return FALSE
+
+/obj/item/twohanded/required/cult_bastard/afterattack(atom/target, mob/user, proximity, click_parameters)
+ . = ..()
+ if(dash_toggled && jaunt.IsAvailable())
+ jaunt.Teleport(user, target)
+ return
+ if(!proximity)
+ return
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(H.stat != CONSCIOUS)
+ var/obj/item/device/soulstone/SS = new /obj/item/device/soulstone(src)
+ SS.attack(H, user)
+ shards += SS
+ return
+ if(istype(target, /obj/structure/constructshell) && contents.len)
+ var/obj/item/device/soulstone/SS = contents[1]
+ if(istype(SS) && SS.transfer_soul("CONSTRUCT",target,user))
+ qdel(SS)
+
+/datum/action/innate/dash/cult
+ name = "Rend the Veil"
+ desc = "Use the sword to shear open the flimsy fabric of this reality and teleport to your target."
+ icon_icon = 'icons/mob/actions/actions_cult.dmi'
+ button_icon_state = "phaseshift"
+ dash_sound = 'sound/magic/enter_blood.ogg'
+ recharge_sound = 'sound/magic/exit_blood.ogg'
+ beam_effect = "sendbeam"
+ phasein = /obj/effect/temp_visual/dir_setting/cult/phase
+ phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out
+
+/datum/action/innate/dash/cult/IsAvailable()
+ if(iscultist(holder) && charged)
+ return TRUE
+ else
+ return FALSE
+
+
+
+/datum/action/innate/cult/spin2win
+ name = "Geometer's Fury"
+ desc = "You draw on the power of the sword's ancient runes, spinning it wildly around you as you become immune to most attacks."
+ background_icon_state = "bg_demon"
+ button_icon_state = "sintouch"
+ var/cooldown = 0
+ var/mob/living/carbon/human/holder
+ var/obj/item/twohanded/required/cult_bastard/sword
+
+/datum/action/innate/cult/spin2win/Grant(mob/user, obj/bastard)
+ . = ..()
+ sword = bastard
+ holder = user
+
+/datum/action/innate/cult/spin2win/IsAvailable()
+ if(iscultist(holder) && cooldown <= world.time)
+ return TRUE
+ else
+ return FALSE
+
+/datum/action/innate/cult/spin2win/Activate()
+ cooldown = world.time + sword.spin_cooldown
+ holder.changeNext_move(50)
+ holder.apply_status_effect(/datum/status_effect/sword_spin)
+ sword.spinning = TRUE
+ sword.block_chance = 100
+ sword.slowdown += 1.5
+ addtimer(CALLBACK(src, .proc/stop_spinning), 50)
+ holder.update_action_buttons_icon()
+
+/datum/action/innate/cult/spin2win/proc/stop_spinning()
+ sword.spinning = FALSE
+ sword.block_chance = 50
+ sword.slowdown -= 1.5
+ sleep(sword.spin_cooldown)
+ holder.update_action_buttons_icon()
/obj/item/restraints/legcuffs/bola/cult
name = "nar'sien bola"
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index c1ccf9a368..0144872c17 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -100,15 +100,21 @@
if(cooldowntime > world.time)
to_chat(user, "The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].")
return
- var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Nar-Sien Hardsuit")
+ var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Bastard Sword")
var/pickedtype
switch(choice)
if("Shielded Robe")
pickedtype = /obj/item/clothing/suit/hooded/cultrobes/cult_shield
if("Flagellant's Robe")
pickedtype = /obj/item/clothing/suit/hooded/cultrobes/berserker
- if("Nar-Sien Hardsuit")
- pickedtype = /obj/item/clothing/suit/space/hardsuit/cult
+ if("Bastard Sword")
+ if((world.time - SSticker.round_start_time) >= 12000)
+ pickedtype = /obj/item/twohanded/required/cult_bastard
+ else
+ cooldowntime = 12000 - (world.time - SSticker.round_start_time)
+ to_chat(user, "The forge fires are not yet hot enough for this weapon, give it another [DisplayTimeText(cooldowntime - world.time)].")
+ cooldowntime = 0
+ return
if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time)
cooldowntime = world.time + 2400
var/obj/item/N = new pickedtype(get_turf(src))
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index df57ded774..149c2ae912 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -199,7 +199,6 @@
SSticker.mode.cult -= A.mind
SSticker.mode.update_cult_icons_removed(A.mind)
qdel(T)
- user.drop_item()
qdel(src)
else
to_chat(user, "Creation failed!: The soul stone is empty! Go kill someone!")
diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm
index dc6993cdbe..28856e17d8 100644
--- a/code/game/objects/items/storage/book.dm
+++ b/code/game/objects/items/storage/book.dm
@@ -156,6 +156,24 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
var/unholy2clean = A.reagents.get_reagent_amount("unholywater")
A.reagents.del_reagent("unholywater")
A.reagents.add_reagent("holywater",unholy2clean)
+ if(istype(A, /obj/item/twohanded/required/cult_bastard))
+ var/obj/item/twohanded/required/cult_bastard/sword = A
+ to_chat(user, "You begin to exorcise [sword].")
+ playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1)
+ if(do_after(user, 40, target = sword))
+ playsound(src,'sound/effects/pray_chaplain.ogg',60,1)
+ for(var/obj/item/device/soulstone/SS in sword.shards)
+ SS.usability = TRUE
+ for(var/mob/living/simple_animal/shade/EX in SS)
+ SSticker.mode.remove_cultist(EX.mind, 1, 0)
+ EX.icon_state = "ghost1"
+ EX.name = "Purified [EX.name]"
+ SS.release_shades(user)
+ qdel(SS)
+ new /obj/item/nullrod/claymore(get_turf(sword))
+ user.visible_message("[user] has purified the [sword]!!")
+ qdel(sword)
+
/obj/item/storage/book/bible/booze
desc = "To be applied to the head repeatedly."
diff --git a/icons/mob/inhands/64x64_lefthand.dmi b/icons/mob/inhands/64x64_lefthand.dmi
index a9a952733a..1b450ab3e0 100644
Binary files a/icons/mob/inhands/64x64_lefthand.dmi and b/icons/mob/inhands/64x64_lefthand.dmi differ
diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi
index bff96a991b..bbeddf9152 100644
Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ
diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi
index 94c0c03835..b5ac65c2a8 100644
Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ
diff --git a/sound/weapons/fwoosh.wav b/sound/weapons/fwoosh.wav
new file mode 100644
index 0000000000..1723c4e9b8
Binary files /dev/null and b/sound/weapons/fwoosh.wav differ
diff --git a/sound/weapons/parry.ogg b/sound/weapons/parry.ogg
new file mode 100644
index 0000000000..1f86716337
Binary files /dev/null and b/sound/weapons/parry.ogg differ