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