diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm
index 15b9ea3ab4b..4278c69a177 100644
--- a/code/__DEFINES/colors.dm
+++ b/code/__DEFINES/colors.dm
@@ -22,8 +22,8 @@
#define COLOR_MAROON "#800000"
#define COLOR_VIVID_RED "#FF3232"
#define COLOR_LIGHT_GRAYISH_RED "#E4C7C5"
-/// Warm but extremely diluted red. rgb(250, 130, 130)
#define COLOR_SOFT_RED "#FA8282"
+#define COLOR_BUBBLEGUM_RED "#950A0A"
#define COLOR_YELLOW "#FFFF00"
#define COLOR_VIVID_YELLOW "#FBFF23"
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 92afd17f6d4..3a89453eee9 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -381,3 +381,5 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define BRAIN_UNAIDED "brain-unaided"
/// Trait applied by element
#define ELEMENT_TRAIT "element_trait"
+/// Trait granted by [/obj/item/clothing/head/helmet/space/hardsuit/berserker]
+#define BERSERK_TRAIT "berserk_trait"
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 3dd4f6810b1..62ed37605db 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -304,10 +304,9 @@
button_icon_state = "vortex_recall"
/datum/action/item_action/vortex_recall/IsAvailable()
- var/turf/current_location = get_turf(target)
- var/area/current_area = current_location.loc
+ var/area/current_area = get_area(target)
if(current_area.area_flags & NOTELEPORT)
- to_chat(target, "[src] fizzles uselessly.")
+ to_chat(owner, "[target] fizzles uselessly.")
return
if(istype(target, /obj/item/hierophant_club))
var/obj/item/hierophant_club/H = target
@@ -315,6 +314,26 @@
return FALSE
return ..()
+/datum/action/item_action/berserk_mode
+ name = "Berserk"
+ desc = "Increase your movement and melee speed while also increasing your melee armor for a short amount of time."
+ icon_icon = 'icons/mob/actions/actions_items.dmi'
+ button_icon_state = "berserk_mode"
+ background_icon_state = "bg_demon"
+
+/datum/action/item_action/berserk_mode/Trigger()
+ if(istype(target, /obj/item/clothing/head/helmet/space/hardsuit/berserker))
+ var/obj/item/clothing/head/helmet/space/hardsuit/berserker/berzerk = target
+ if(berzerk.berserk_active)
+ to_chat(owner, "You are already berserk!")
+ return
+ if(berzerk.berserk_charge < 100)
+ to_chat(owner, "You don't have a full charge.")
+ return
+ berzerk.berserk_mode(owner)
+ return
+ ..()
+
/datum/action/item_action/toggle_helmet_flashlight
name = "Toggle Helmet Flashlight"
diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm
index 03b1e860dd2..8c1c3577a16 100644
--- a/code/modules/clothing/spacesuits/miscellaneous.dm
+++ b/code/modules/clothing/spacesuits/miscellaneous.dm
@@ -360,10 +360,6 @@ Contains:
actions_types = list()
resistance_flags = FIRE_PROOF
-/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
- . = ..()
- AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_OCLOTHING)
-
/obj/item/clothing/suit/space/hardsuit/ert/paranormal
name = "paranormal response team hardsuit"
desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats."
@@ -389,19 +385,113 @@ Contains:
inhand_icon_state = "hardsuit0-inq"
hardsuit_type = "inq"
-/obj/item/clothing/suit/space/hardsuit/ert/paranormal/berserker
- name = "champion's hardsuit"
+/obj/item/clothing/suit/space/hardsuit/berserker
+ name = "berserker hardsuit"
desc = "Voices echo from the hardsuit, driving the user insane."
icon_state = "hardsuit-berserker"
inhand_icon_state = "hardsuit-berserker"
- helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/berserker
+ slowdown = 0
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/berserker
+ armor = list(MELEE = 30, BULLET = 10, LASER = 10, ENERGY = 20, BOMB = 10, BIO = 100, RAD = 10, FIRE = 100, ACID = 100)
+ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
+ resistance_flags = FIRE_PROOF
+ allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/pickaxe, /obj/item/spear, /obj/item/organ/regenerative_core/legion, /obj/item/kitchen/knife, /obj/item/kinetic_crusher, /obj/item/resonator, /obj/item/melee/transforming/cleaving_saw)
-/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/berserker
- name = "champion's helmet"
+
+/obj/item/clothing/suit/space/hardsuit/berserker/Initialize()
+ . = ..()
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, TRUE, ITEM_SLOT_OCLOTHING)
+
+/obj/item/clothing/suit/space/hardsuit/berserker/RemoveHelmet()
+ var/obj/item/clothing/head/helmet/space/hardsuit/berserker/helm = helmet
+ if(helm?.berserk_active)
+ return
+ return ..()
+
+#define MAX_BERSERK_CHARGE 100
+#define PROJECTILE_HIT_MULTIPLIER 1.5
+#define DAMAGE_TO_CHARGE_SCALE 0.25
+#define CHARGE_DRAINED_PER_SECOND 5
+#define BERSERK_MELEE_ARMOR_ADDED 50
+#define BERSERK_ATTACK_SPEED_MODIFIER 0.25
+
+/obj/item/clothing/head/helmet/space/hardsuit/berserker
+ name = "berserker helmet"
desc = "Peering into the eyes of the helmet is enough to seal damnation."
icon_state = "hardsuit0-berserker"
inhand_icon_state = "hardsuit0-berserker"
hardsuit_type = "berserker"
+ armor = list(MELEE = 30, BULLET = 10, LASER = 10, ENERGY = 20, BOMB = 10, BIO = 100, RAD = 10, FIRE = 100, ACID = 100)
+ actions_types = list(/datum/action/item_action/berserk_mode)
+ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
+ resistance_flags = FIRE_PROOF
+ /// Current charge of berserk, goes from 0 to 100
+ var/berserk_charge = 0
+ /// Status of berserk
+ var/berserk_active = FALSE
+
+/obj/item/clothing/head/helmet/space/hardsuit/berserker/Initialize()
+ . = ..()
+ ADD_TRAIT(src, TRAIT_NODROP, LOCKED_HELMET_TRAIT)
+
+/obj/item/clothing/head/helmet/space/hardsuit/berserker/examine()
+ . = ..()
+ . += "Berserk mode is [berserk_charge]% charged."
+
+/obj/item/clothing/head/helmet/space/hardsuit/berserker/process(delta_time)
+ . = ..()
+ if(berserk_active)
+ berserk_charge = clamp(berserk_charge - CHARGE_DRAINED_PER_SECOND * delta_time, 0, MAX_BERSERK_CHARGE)
+ if(!berserk_charge)
+ if(ishuman(loc))
+ end_berserk(loc)
+
+/obj/item/clothing/head/helmet/space/hardsuit/berserker/dropped(mob/user)
+ . = ..()
+ end_berserk(user)
+
+/obj/item/clothing/head/helmet/space/hardsuit/berserker/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(berserk_active)
+ return
+ var/berserk_value = damage * DAMAGE_TO_CHARGE_SCALE
+ if(attack_type == PROJECTILE_ATTACK)
+ berserk_value *= PROJECTILE_HIT_MULTIPLIER
+ berserk_charge = clamp(round(berserk_charge + berserk_value), 0, MAX_BERSERK_CHARGE)
+ if(berserk_charge >= MAX_BERSERK_CHARGE)
+ to_chat(owner, "Berserk mode is fully charged.")
+
+/// Starts berserk, giving the wearer 50 melee armor, doubled attacking speed, NOGUNS trait, adding a color and giving them the berserk movespeed modifier
+/obj/item/clothing/head/helmet/space/hardsuit/berserker/proc/berserk_mode(mob/living/carbon/human/user)
+ to_chat(user, "You enter berserk mode.")
+ playsound(user, 'sound/magic/staff_healing.ogg', 50)
+ user.add_movespeed_modifier(/datum/movespeed_modifier/berserk)
+ user.physiology.armor.melee += BERSERK_MELEE_ARMOR_ADDED
+ user.next_move_modifier *= BERSERK_ATTACK_SPEED_MODIFIER
+ user.add_atom_colour(COLOR_BUBBLEGUM_RED, TEMPORARY_COLOUR_PRIORITY)
+ ADD_TRAIT(user, TRAIT_NOGUNS, BERSERK_TRAIT)
+ ADD_TRAIT(src, TRAIT_NODROP, BERSERK_TRAIT)
+ berserk_active = TRUE
+
+/// Ends berserk, reverting the changes from the proc [berserk_mode]
+/obj/item/clothing/head/helmet/space/hardsuit/berserker/proc/end_berserk(mob/living/carbon/human/user)
+ if(!berserk_active)
+ return
+ to_chat(user, "You exit berserk mode.")
+ playsound(user, 'sound/magic/summonitems_generic.ogg', 50)
+ user.remove_movespeed_modifier(/datum/movespeed_modifier/berserk)
+ user.physiology.armor.melee -= BERSERK_MELEE_ARMOR_ADDED
+ user.next_move_modifier /= BERSERK_ATTACK_SPEED_MODIFIER
+ user.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, COLOR_BUBBLEGUM_RED)
+ REMOVE_TRAIT(user, TRAIT_NOGUNS, BERSERK_TRAIT)
+ REMOVE_TRAIT(src, TRAIT_NODROP, BERSERK_TRAIT)
+ berserk_active = FALSE
+
+#undef MAX_BERSERK_CHARGE
+#undef PROJECTILE_HIT_MULTIPLIER
+#undef DAMAGE_TO_CHARGE_SCALE
+#undef CHARGE_DRAINED_PER_SECOND
+#undef BERSERK_MELEE_ARMOR_ADDED
+#undef BERSERK_ATTACK_SPEED_MODIFIER
/obj/item/clothing/head/helmet/space/fragile
name = "emergency space helmet"
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index d76012130ee..7340b8da011 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -45,7 +45,7 @@
if(10)
new /obj/item/ship_in_a_bottle(src)
if(11)
- new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/berserker(src)
+ new /obj/item/clothing/suit/space/hardsuit/berserker(src)
if(12)
new /obj/item/jacobs_ladder(src)
if(13)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 67369b4b7bf..4e48bd4fea6 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -132,6 +132,10 @@
var/final_block_chance = wear_neck.block_chance - (clamp((armour_penetration-wear_neck.armour_penetration)/2,0,100)) + block_chance_modifier
if(wear_neck.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return TRUE
+ if(head)
+ var/final_block_chance = head.block_chance - (clamp((armour_penetration-head.armour_penetration)/2,0,100)) + block_chance_modifier
+ if(head.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
+ return TRUE
return FALSE
/mob/living/carbon/human/proc/check_block()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index 6b8a0f88562..f4d12c108cc 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -345,15 +345,14 @@ Difficulty: Hard
enrage_till = world.time + enrage_time
update_approach()
change_move_delay(3.75)
- var/newcolor = rgb(149, 10, 10)
- add_atom_colour(newcolor, TEMPORARY_COLOUR_PRIORITY)
+ add_atom_colour(COLOR_BUBBLEGUM_RED, TEMPORARY_COLOUR_PRIORITY)
var/datum/callback/cb = CALLBACK(src, .proc/blood_enrage_end)
addtimer(cb, enrage_time)
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_enrage_end(newcolor = rgb(149, 10, 10))
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_enrage_end()
update_approach()
change_move_delay()
- remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, newcolor)
+ remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, COLOR_BUBBLEGUM_RED)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/change_move_delay(newmove = initial(move_to_delay))
move_to_delay = newmove
diff --git a/code/modules/movespeed/modifiers/items.dm b/code/modules/movespeed/modifiers/items.dm
index e36c05dccee..32f5756e084 100644
--- a/code/modules/movespeed/modifiers/items.dm
+++ b/code/modules/movespeed/modifiers/items.dm
@@ -10,3 +10,6 @@
/datum/movespeed_modifier/die_of_fate
multiplicative_slowdown = 1
+
+/datum/movespeed_modifier/berserk
+ multiplicative_slowdown = -0.2
diff --git a/icons/mob/actions/actions_items.dmi b/icons/mob/actions/actions_items.dmi
index f62070d79c7..a68aaab9bf9 100644
Binary files a/icons/mob/actions/actions_items.dmi and b/icons/mob/actions/actions_items.dmi differ
diff --git a/icons/mob/clothing/belt_mirror.dmi b/icons/mob/clothing/belt_mirror.dmi
index b5a209f6290..3495f34ce65 100644
Binary files a/icons/mob/clothing/belt_mirror.dmi and b/icons/mob/clothing/belt_mirror.dmi differ