diff --git a/ModularTegustation/Teguicons/96x48.dmi b/ModularTegustation/Teguicons/96x48.dmi
index dc0daa343c83..c104292bfef1 100644
Binary files a/ModularTegustation/Teguicons/96x48.dmi and b/ModularTegustation/Teguicons/96x48.dmi differ
diff --git a/ModularTegustation/tegu_items/debug_items.dm b/ModularTegustation/tegu_items/debug_items.dm
index bb3a91d4e23b..e9acde38e55e 100644
--- a/ModularTegustation/tegu_items/debug_items.dm
+++ b/ModularTegustation/tegu_items/debug_items.dm
@@ -373,3 +373,26 @@
say("Restarting...")
SLEEP_CHECK_DEATH(10)
DeepsCheckStart()
+
+//breach tester
+/obj/item/breachtester//for testing many abnormalities very quickly
+ name = "Breach tester"
+ desc = "For testing use only, DO NOT DISTRIBUTE! Breach types can be checked under _DEFINES/abnormalities.dm"
+ icon = 'icons/obj/items_and_weapons.dmi'
+ icon_state = "nanoimplant"
+ var/breach_type = BREACH_NORMAL
+ var/list/breach_list = list(
+ BREACH_NORMAL, BREACH_PINK, BREACH_MINING,
+ )
+
+/obj/item/breachtester/attack_self(mob/user)
+ breach_type = input(user, "Which breach will you test?") as null|anything in breach_list
+
+/obj/item/breachtester/attack(mob/living/simple_animal/hostile/abnormality/target, mob/living/carbon/human/user)
+ if(!isabnormalitymob(target))
+ to_chat(user, span_warning("\"[target]\" isn't an Abnormality."))
+ return
+ target.BreachEffect(user, breach_type)
+ to_chat(user, span_nicegreen("You triggered a [breach_type] breach!"))
+
+
diff --git a/code/__DEFINES/abnormalities.dm b/code/__DEFINES/abnormalities.dm
index 71b708ef510b..5a254c6f0d93 100644
--- a/code/__DEFINES/abnormalities.dm
+++ b/code/__DEFINES/abnormalities.dm
@@ -14,6 +14,7 @@
// Breach types
#define BREACH_NORMAL 0
#define BREACH_PINK 1
+#define BREACH_MINING 2
// List
#define THREAT_TO_NAME list(\
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/army_in_black.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/army_in_black.dm
index f134732caea4..d3834f71db58 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/army_in_black.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/army_in_black.dm
@@ -150,9 +150,14 @@ GLOBAL_LIST_EMPTY(army)
//*--Combat Mechanics--*
/mob/living/simple_animal/hostile/abnormality/army/BreachEffect(mob/living/carbon/human/user, breach_type)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_ABNORMALITY_BREACH, src)
- FearEffect()
- Blackify()
- SpawnAdds()//set its alpha to 0 and make it non-dense
+ if(breach_type == BREACH_MINING)
+ for(var/i = 1 to 3)
+ var/mob/living/simple_animal/hostile/army_enemy/E = new(get_turf(src))
+ RegisterSignal(E, COMSIG_PARENT_QDELETING, PROC_REF(ArmyDeath))
+ else
+ FearEffect()
+ Blackify()
+ SpawnAdds()//set its alpha to 0 and make it non-dense
for(var/mob/living/L in protected_targets)
L.remove_status_effect(STATUS_EFFECT_PROTECTION)
density = FALSE
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/blue_star.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/blue_star.dm
index ec9e78aa5d29..3d89216cc30d 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/blue_star.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/blue_star.dm
@@ -138,6 +138,7 @@
. = ..()
var/turf/T = pick(GLOB.department_centers)
soundloop.start()
- forceMove(T)
+ if(breach_type != BREACH_MINING)
+ forceMove(T)
BluePulse()
return
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/distortedform.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/distortedform.dm
index 5d5d8e8b2053..d5ec87b66aae 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/distortedform.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/distortedform.dm
@@ -300,6 +300,9 @@
//Breach
/mob/living/simple_animal/hostile/abnormality/distortedform/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ qdel(src)
+ return
. = ..()
if(breached)
return
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/last_shot.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/last_shot.dm
index 9a6efb684e8f..6c9b3a28d844 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/last_shot.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/last_shot.dm
@@ -61,7 +61,10 @@ GLOBAL_LIST_EMPTY(meat_list)
/mob/living/simple_animal/hostile/abnormality/last_shot/Move()
return FALSE
-/mob/living/simple_animal/hostile/abnormality/last_shot/BreachEffect()
+/mob/living/simple_animal/hostile/abnormality/last_shot/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ ..()
+ return
var/turf/T = pick(GLOB.department_centers)
forceMove(T)
..()
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/nobody_is.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/nobody_is.dm
index 44703d2803a0..cf7a2773e7d8 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/nobody_is.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/nobody_is.dm
@@ -231,7 +231,7 @@
datum_reference.qliphoth_change(-1)
/mob/living/simple_animal/hostile/abnormality/nobody_is/BreachEffect(mob/living/carbon/human/user, breach_type)
- if(!(status_flags & GODMODE)) // Already breaching
+ if(current_stage > 1)
return
if(reflect_timer)
deltimer(reflect_timer)
@@ -240,6 +240,8 @@
return
CheckMirrorIcon() //Clear overlays
next_stage()
+ if(breach_type == BREACH_MINING)
+ return
// Teleport us somewhere where nobody will see us at first
var/list/priority_list = list()
for(var/turf/T in GLOB.xeno_spawn)
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/seasons.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/seasons.dm
index b71ac42ce4a1..0d6547c0b743 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/seasons.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/seasons.dm
@@ -322,8 +322,9 @@
ZeroQliphoth()
return
. = ..()
- var/turf/T = pick(GLOB.department_centers)
- forceMove(T)
+ if(breach_type != BREACH_MINING)
+ var/turf/T = pick(GLOB.department_centers)
+ forceMove(T)
//Weather controlling
/mob/living/simple_animal/hostile/abnormality/seasons/proc/CheckWeather()
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/silent_orchestra.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/silent_orchestra.dm
index f59c6b39bbe2..cb096b1608f4 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/silent_orchestra.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/silent_orchestra.dm
@@ -154,8 +154,9 @@
/mob/living/simple_animal/hostile/abnormality/silentorchestra/BreachEffect(mob/living/carbon/human/user, breach_type)
. = ..()
- var/turf/T = pick(GLOB.department_centers)
- forceMove(T)
+ if(breach_type != BREACH_MINING)
+ var/turf/T = pick(GLOB.department_centers)
+ forceMove(T)
DamagePulse()
return
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/space_lady.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/space_lady.dm
index 7bf0e34b9883..b1fd4da49eef 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/space_lady.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/space_lady.dm
@@ -261,7 +261,8 @@
/mob/living/simple_animal/hostile/abnormality/space_lady/BreachEffect(mob/living/carbon/human/user, breach_type)
. = ..()
- Teleport()
+ if(breach_type != BREACH_MINING)
+ Teleport()
//Bullets
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/white_night.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/white_night.dm
index 0cbd36d1f7d0..dc5033d17a4e 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/white_night.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/white_night.dm
@@ -221,6 +221,9 @@ GLOBAL_LIST_EMPTY(apostles)
return
/mob/living/simple_animal/hostile/abnormality/white_night/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ qdel(src)
+ return
holy_revival_cooldown = world.time + holy_revival_cooldown_base
. = ..()
for(var/mob/M in GLOB.player_list)
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/doomsday_calendar.dm b/code/modules/mob/living/simple_animal/abnormality/he/doomsday_calendar.dm
index acc1dcd9d956..fbdb5c13350a 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/doomsday_calendar.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/doomsday_calendar.dm
@@ -188,9 +188,10 @@
//***Breach Mechanics***//
/mob/living/simple_animal/hostile/abnormality/doomsday_calendar/BreachEffect(mob/living/carbon/human/user, breach_type)
. = ..()
- var/turf/T = pick(GLOB.department_centers)
+ if(breach_type != BREACH_MINING)
+ var/turf/T = pick(GLOB.department_centers)
+ forceMove(T)
icon_state = "doomsday_active"
- forceMove(T)
AnnounceBreach()
SpawnAdds()
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/highway_devotee.dm b/code/modules/mob/living/simple_animal/abnormality/he/highway_devotee.dm
index f10a2c18fd2e..d6905489f1c7 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/highway_devotee.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/highway_devotee.dm
@@ -90,8 +90,9 @@
/mob/living/simple_animal/hostile/abnormality/highway_devotee/BreachEffect(mob/living/carbon/human/user, breach_type)
. = ..()
- var/turf/T = pick(GLOB.xeno_spawn)
- forceMove(T)
+ if(breach_type != BREACH_MINING)
+ var/turf/T = pick(GLOB.xeno_spawn)
+ forceMove(T)
addtimer(CALLBACK(src, PROC_REF(KillYourself)), 3 MINUTES)
dir = pick(list(NORTH, SOUTH, WEST, EAST))
for(var/turf/open/U in range(2, src))
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/jangsan.dm b/code/modules/mob/living/simple_animal/abnormality/he/jangsan.dm
index c5d138cc532f..60b259497c51 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/jangsan.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/jangsan.dm
@@ -193,7 +193,8 @@
. = ..()
if(!datum_reference.abno_radio)
AbnoRadio()
- addtimer(CALLBACK(src, PROC_REF(TryTeleport)), 5)
+ if(breach_type != BREACH_MINING)
+ addtimer(CALLBACK(src, PROC_REF(TryTeleport)), 5)
/mob/living/simple_animal/hostile/abnormality/jangsan/proc/TryTeleport() //stolen from knight of despair
dir = 2
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/laetitia.dm b/code/modules/mob/living/simple_animal/abnormality/he/laetitia.dm
index 5cde37ce7594..a12ca13c2ae7 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/laetitia.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/laetitia.dm
@@ -42,6 +42,10 @@
You look lonely too, I hope my present will make you laugh as well!"
attack_action_types = list(/datum/action/cooldown/laetitia_gift, /datum/action/cooldown/laetitia_summon)
+ var/breaching = FALSE
+ var/summon_cooldown
+ var/summon_cooldown_time = 60 SECONDS
+ var/summon_list = list()
/datum/action/cooldown/laetitia_summon
name = "Call for Friends"
@@ -49,7 +53,7 @@
button_icon_state = "prank_gift"
check_flags = AB_CHECK_CONSCIOUS
transparent_when_unavailable = TRUE
- cooldown_time = 40 SECONDS
+ cooldown_time = 60 SECONDS
var/delete_timer
var/delete_cooldown = 30 SECONDS
var/mob/living/simple_animal/hostile/gift/G1
@@ -139,6 +143,13 @@
qdel(src)
opening = FALSE
+/mob/living/simple_animal/hostile/abnormality/laetitia/Life()
+ . = ..()
+ if(!breaching)
+ return
+ if((summon_cooldown < world.time) && !(status_flags & GODMODE))
+ SummonAdds()
+ return
/mob/living/simple_animal/hostile/abnormality/laetitia/NeutralEffect(mob/living/carbon/human/user, work_type, pe)
. = ..()
@@ -168,6 +179,19 @@
P.TriggerPrank()
return
+/mob/living/simple_animal/hostile/abnormality/laetitia/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ breaching = TRUE
+ return ..()
+
+/mob/living/simple_animal/hostile/abnormality/laetitia/proc/SummonAdds()//Mining breach summon
+ summon_cooldown = world.time + summon_cooldown_time
+ if(LAZYLEN(summon_list) > 9)//this list is not subtracted when minions are killed. Limited to 10 per breach
+ return
+ var/turf/target_turf = get_turf(src)
+ var/mob/living/simple_animal/hostile/gift/new_mob = new(target_turf)
+ summon_list += new_mob
+
//Her friend
/mob/living/simple_animal/hostile/gift
name = "Little Witch's Friend"
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/porccubus.dm b/code/modules/mob/living/simple_animal/abnormality/he/porccubus.dm
index 74dbbe1ae7de..0ec6a983ead6 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/porccubus.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/porccubus.dm
@@ -59,6 +59,7 @@
var/teleport_cooldown_time = 5 MINUTES
var/teleport_cooldown
var/damage_taken = FALSE
+ var/noteleport = FALSE
//PLAYABLE ATTACKS
attack_action_types = list(/datum/action/innate/abnormality_attack/toggle/porccubus_dash_toggle)
@@ -132,11 +133,13 @@
//it does have a dash that makes it able to jump around, but it can't properly "roam" per say.
/mob/living/simple_animal/hostile/abnormality/porccubus/BreachEffect(mob/living/carbon/human/user, breach_type)
. = ..()
+ if(breach_type == BREACH_MINING)
+ noteleport = TRUE
playsound(src, 'sound/abnormalities/porccubus/head_explode_laugh.ogg', 50, FALSE, 4)
icon_living = "porrcubus"
icon_state = icon_living
ranged_cooldown = world.time + ranged_cooldown_time
- if(!IsCombatMap())
+ if(!IsCombatMap() && (breach_type != BREACH_MINING))
var/turf/T = pick(GLOB.xeno_spawn)
forceMove(T)
teleport_cooldown = world.time + teleport_cooldown_time
@@ -148,7 +151,7 @@
. = ..()
if(status_flags & GODMODE)
return
- if(IsCombatMap())
+ if(IsCombatMap() || noteleport)
return
if(teleport_cooldown < world.time) //if porccubus hasn't taken damage for 5 minutes we make him move so he doesn't stay stuck in whatever cell he got thrown in.
teleport_cooldown = world.time + teleport_cooldown_time
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/red_shoes.dm b/code/modules/mob/living/simple_animal/abnormality/he/red_shoes.dm
index 6191e2e632fe..178e4484b454 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/red_shoes.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/red_shoes.dm
@@ -201,8 +201,6 @@
//BreachEffect and combat
/mob/living/simple_animal/hostile/abnormality/red_shoes/BreachEffect(mob/living/carbon/human/user, breach_type)
- if(!(status_flags & GODMODE))
- return
soundloop.stop()
for(var/mob/living/carbon/human/H in GLOB.mob_living_list)//stops possessing people, prevents runtimes. Panicked players are ghosted so use mob_living_list
UnPossess(H)
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/singing_machine.dm b/code/modules/mob/living/simple_animal/abnormality/he/singing_machine.dm
index 613a8844b531..3f95aa3cda64 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/singing_machine.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/singing_machine.dm
@@ -10,8 +10,8 @@ Finally, an abnormality that DOESN'T have to do any fancy movement shit. It's a
icon_state = "singingmachine_closed_clean"
icon_living = "singingmachine_closed_clean"
portrait = "singing_machine"
- maxHealth = 200
- health = 200
+ maxHealth = 3000
+ health = 3000
threat_level = HE_LEVEL
start_qliphoth = 2
work_chances = list(
@@ -71,6 +71,12 @@ Finally, an abnormality that DOESN'T have to do any fancy movement shit. It's a
to_chat(H, span_warning("That terrible grinding noise..."))
return ..()
+/mob/living/simple_animal/hostile/abnormality/singing_machine/Move()
+ return FALSE
+
+/mob/living/simple_animal/hostile/abnormality/singing_machine/CanAttack(atom/the_target)
+ return FALSE
+
/mob/living/simple_animal/hostile/abnormality/singing_machine/AttemptWork(mob/living/carbon/human/user, work_type)
if(work_type == ABNORMALITY_WORK_INSTINCT)
if(datum_reference.qliphoth_meter > 0) // Sets bonus damage on instinct work.
@@ -148,6 +154,10 @@ Finally, an abnormality that DOESN'T have to do any fancy movement shit. It's a
playStatus = 1
return
+/mob/living/simple_animal/hostile/abnormality/singing_machine/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ ZeroQliphoth()
+
/mob/living/simple_animal/hostile/abnormality/singing_machine/proc/removeAddict(mob/living/carbon/human/addict)
if(addict)
musicalAddicts -= addict // Your five minutes are over, you're free.
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/snow_queen.dm b/code/modules/mob/living/simple_animal/abnormality/he/snow_queen.dm
index 4cfbd50e6666..acf2c5155533 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/snow_queen.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/snow_queen.dm
@@ -163,7 +163,7 @@
faction += "pink_midnight"
//Call root code but with normal breach
. = ..(null, BREACH_NORMAL)
- if(!IsCombatMap())
+ if(!IsCombatMap() && breach_type != BREACH_MINING)
var/turf/T = pick(GLOB.department_centers)
forceMove(T)
update_icon()
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/you_strong.dm b/code/modules/mob/living/simple_animal/abnormality/he/you_strong.dm
index fc03e9af235c..295ac1ca20b0 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/you_strong.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/you_strong.dm
@@ -5,8 +5,9 @@
icon_state = "you_strong_pause"
icon_living = "you_strong_pause"
portrait = "grown_strong"
- maxHealth = 200
- health = 200
+ maxHealth = 2000
+ health = 2000
+ damage_coeff = list(RED_DAMAGE = 1, WHITE_DAMAGE = 1.5, BLACK_DAMAGE = 1.5, PALE_DAMAGE = 0)
threat_level = HE_LEVEL
start_qliphoth = 3
work_chances = list(
@@ -61,6 +62,10 @@
var/datum/looping_sound/server/soundloop
var/operating = FALSE
+ var/breaching = FALSE
+ var/summon_cooldown
+ var/summon_cooldown_time = 120 SECONDS
+ var/summon_list = list()
/mob/living/simple_animal/hostile/abnormality/you_strong/Initialize(mapload)
. = ..()
@@ -68,6 +73,20 @@
soundloop.volume = 75
soundloop.extra_range = 0
+/mob/living/simple_animal/hostile/abnormality/you_strong/Move()
+ return FALSE
+
+/mob/living/simple_animal/hostile/abnormality/you_strong/CanAttack(atom/the_target)
+ return FALSE
+
+/mob/living/simple_animal/hostile/abnormality/you_strong/Life()
+ . = ..()
+ if(!breaching)
+ return
+ if((summon_cooldown < world.time) && !(status_flags & GODMODE))
+ SummonAdds()
+ return
+
/mob/living/simple_animal/hostile/abnormality/you_strong/WorkComplete(mob/living/carbon/human/user, work_type, pe, work_time, canceled)
. = ..()
if(work_type == ABNORMALITY_WORK_REPRESSION)
@@ -123,14 +142,28 @@
icon_state = "you_strong_work"
SLEEP_CHECK_DEATH(30 SECONDS)
soundloop.stop()
- src.datum_reference.qliphoth_change(3)
+ if(datum_reference)
+ src.datum_reference.qliphoth_change(3)
icon_state = "you_strong_make"
SLEEP_CHECK_DEATH(6)
for(var/i = 1 to 3)
new /mob/living/simple_animal/hostile/grown_strong(get_step(src, EAST))
+ if(breaching)
+ summon_list += /mob/living/simple_animal/hostile/grown_strong
SLEEP_CHECK_DEATH(6)
icon_state = "you_strong_pause"
+/mob/living/simple_animal/hostile/abnormality/you_strong/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ breaching = TRUE
+ return ..()
+
+/mob/living/simple_animal/hostile/abnormality/you_strong/proc/SummonAdds()
+ summon_cooldown = world.time + summon_cooldown_time
+ if(LAZYLEN(summon_list) > 9)//this list is not subtracted when minions are killed. Limited to 10 per breach
+ return
+ ZeroQliphoth()
+
/mob/living/simple_animal/hostile/abnormality/you_strong/attacked_by(obj/item/I, mob/living/user)
if(!(I.type in taken_parts))
return ..()
diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/blood_bath.dm b/code/modules/mob/living/simple_animal/abnormality/teth/blood_bath.dm
index eb0badeb1c16..6371d6695dd5 100644
--- a/code/modules/mob/living/simple_animal/abnormality/teth/blood_bath.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/teth/blood_bath.dm
@@ -4,8 +4,17 @@
icon = 'ModularTegustation/Teguicons/48x64.dmi'
icon_state = "bloodbath"
portrait = "blood_bath"
- maxHealth = 400
- health = 400
+ maxHealth = 1000
+ health = 1000
+ move_to_delay = 3
+ attack_sound = 'sound/abnormalities/ichthys/slap.ogg'
+ attack_verb_continuous = "mauls"
+ attack_verb_simple = "maul"
+ melee_damage_lower = 6
+ melee_damage_upper = 12
+ melee_damage_type = WHITE_DAMAGE
+ damage_coeff = list(RED_DAMAGE = 1.6, WHITE_DAMAGE = 1, BLACK_DAMAGE = 1.4, PALE_DAMAGE = 1.5)
+ ranged = TRUE
threat_level = TETH_LEVEL
work_chances = list(
ABNORMALITY_WORK_INSTINCT = list(55, 55, 50, 50, 50),
@@ -38,6 +47,8 @@
observation_fail_message = "You looked away.
This is not the first time you ignore them.
It will be the same afterwards."
var/hands = 0
+ var/can_act = TRUE
+ var/special_attack_cooldown
/mob/living/simple_animal/hostile/abnormality/bloodbath/PostWorkEffect(mob/living/carbon/human/user, work_type, pe, work_time)
// any work performed with level 1 Fort and Temperance makes you panic and die
@@ -67,3 +78,50 @@
datum_reference.max_boxes = max_boxes
icon_state = "bloodbath"
return
+
+/mob/living/simple_animal/hostile/abnormality/bloodbath/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type != BREACH_MINING && breach_type != BREACH_PINK)
+ return
+ if(breach_type == BREACH_PINK)
+ maxHealth = 4000
+ melee_damage_lower = 20
+ melee_damage_upper = 40
+ ..()
+ icon_state = "bloodbath_DF"
+ pixel_x = -8
+ base_pixel_x = -8
+ update_icon()
+
+/mob/living/simple_animal/hostile/abnormality/bloodbath/OpenFire()
+ if(!can_act)
+ return
+ if(special_attack_cooldown > world.time)
+ return
+ BloodBathSlam()
+
+/mob/living/simple_animal/hostile/abnormality/bloodbath/proc/BloodBathSlam()//weaker version of the DF form
+ if(!can_act)
+ return
+ special_attack_cooldown = world.time + 5 SECONDS
+ can_act = FALSE
+ for(var/turf/L in view(3, src))
+ new /obj/effect/temp_visual/cult/sparks(L)
+ playsound(get_turf(src), 'sound/abnormalities/ichthys/jump.ogg', 100, FALSE, 6)
+ icon_state = "bloodbath_slamprepare"
+ SLEEP_CHECK_DEATH(12)
+ for(var/turf/T in view(3, src))
+ var/obj/effect/temp_visual/small_smoke/halfsecond/FX = new(T)
+ FX.color = "#b52e19"
+ for(var/mob/living/carbon/human/H in HurtInTurf(T, list(), 50, WHITE_DAMAGE, null, null, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE))
+ if(H.sanity_lost)
+ H.gib()
+ playsound(get_turf(src), 'sound/abnormalities/bloodbath/Bloodbath_EyeOn.ogg', 125, FALSE, 6)
+ icon_state = "bloodbath_slam"
+ SLEEP_CHECK_DEATH(3)
+ icon_state = "bloodbath_DF"
+ can_act = TRUE
+
+/mob/living/simple_animal/hostile/abnormality/bloodbath/Move()
+ if(!can_act)
+ return FALSE
+ ..()
diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/book.dm b/code/modules/mob/living/simple_animal/abnormality/teth/book.dm
index 580e9768ee69..f40766ee60e6 100644
--- a/code/modules/mob/living/simple_animal/abnormality/teth/book.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/teth/book.dm
@@ -41,6 +41,9 @@
)
var/meltdown_cooldown //no spamming the meltdown effect
var/meltdown_cooldown_time = 30 SECONDS
+ var/breaching = FALSE
+ var/summon_list = list()
+
/mob/living/simple_animal/hostile/abnormality/book/PostWorkEffect(mob/living/carbon/human/user, work_type, pe, work_time)
if(work_type == ABNORMALITY_WORK_REPRESSION)
@@ -103,6 +106,23 @@
if((initial(abno.threat_level)) <= TETH_LEVEL)
nasties += abno
+/mob/living/simple_animal/hostile/abnormality/book/Life()
+ . = ..()
+ if(!breaching)
+ return
+ if(LAZYLEN(summon_list) > 15)
+ qdel(src)
+ return
+ if((meltdown_cooldown < world.time) && !(status_flags & GODMODE))
+ MeltdownEffect()
+ meltdown_cooldown = world.time + meltdown_cooldown_time
+
+/mob/living/simple_animal/hostile/abnormality/book/Move()
+ return FALSE
+
+/mob/living/simple_animal/hostile/abnormality/book/CanAttack(atom/the_target)
+ return FALSE
+
/mob/living/simple_animal/hostile/abnormality/book/proc/RipPages()
var/mob/living/simple_animal/newspawn
if(wordcount >= 3)
@@ -138,7 +158,7 @@
/mob/living/simple_animal/hostile/abnormality/book/ZeroQliphoth(mob/living/carbon/human/user)
datum_reference.qliphoth_change(start_qliphoth) //no need for qliphoth to be stuck at 0
- if(meltdown_cooldown > world.time)
+ if(meltdown_cooldown < world.time)
return
meltdown_cooldown = world.time + meltdown_cooldown_time
MeltdownEffect()
@@ -151,3 +171,9 @@
sleep(0.5 SECONDS)
newspawn = pick(nasties)
SpawnMob(newspawn)
+ if(breaching)
+ summon_list += newspawn
+
+/mob/living/simple_animal/hostile/abnormality/book/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ breaching = TRUE
diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/faelantern.dm b/code/modules/mob/living/simple_animal/abnormality/teth/faelantern.dm
index 71d826514fe1..b2f8702d595a 100644
--- a/code/modules/mob/living/simple_animal/abnormality/teth/faelantern.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/teth/faelantern.dm
@@ -108,6 +108,12 @@
/mob/living/simple_animal/hostile/abnormality/faelantern/BreachEffect(mob/living/carbon/human/user, breach_type)
. = ..()
+ if(breach_type == BREACH_MINING)
+ fairy_enabled = TRUE
+ fairy_health = health
+ can_act = TRUE
+ icon_state = icon_living
+ return
INVOKE_ASYNC(src, PROC_REF(BreachDig))
return
diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/falada.dm b/code/modules/mob/living/simple_animal/abnormality/teth/falada.dm
index 90c185e75414..9e5a4b7e514d 100644
--- a/code/modules/mob/living/simple_animal/abnormality/teth/falada.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/teth/falada.dm
@@ -69,6 +69,11 @@
datum_reference.qliphoth_change(1)
return
+/mob/living/simple_animal/hostile/abnormality/falada/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ pissed()
+ qdel(src)
+
/mob/living/simple_animal/hostile/abnormality/falada/WorkChance(mob/living/carbon/human/user, chance)
if(happy)
chance+=30
diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/meat_lantern.dm b/code/modules/mob/living/simple_animal/abnormality/teth/meat_lantern.dm
index 1b5dbb190dc8..c338f2c9d611 100644
--- a/code/modules/mob/living/simple_animal/abnormality/teth/meat_lantern.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/teth/meat_lantern.dm
@@ -146,6 +146,9 @@
return
/mob/living/simple_animal/hostile/abnormality/meat_lantern/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)//as funny as it sounds, this abnormality would be unreachable
+ qdel(src)
+ return
. = ..()
update_icon()
density = FALSE
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/alriune.dm b/code/modules/mob/living/simple_animal/abnormality/waw/alriune.dm
index 96ccecb95f18..cca14b4beade 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/alriune.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/alriune.dm
@@ -160,7 +160,8 @@
/mob/living/simple_animal/hostile/abnormality/alriune/BreachEffect(mob/living/carbon/human/user, breach_type)
. = ..()
petals_next = world.time + petals_next_time + 30
- TeleportAway()
+ if(breach_type != BREACH_MINING)//in ER you get a few seconds to smack it down
+ TeleportAway()
icon_state = "alriune_active"
return
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/black_swan.dm b/code/modules/mob/living/simple_animal/abnormality/waw/black_swan.dm
index aeb3656a878c..d0fd2b5cab59 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/black_swan.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/black_swan.dm
@@ -157,7 +157,8 @@
if(!LAZYLEN(teleport_potential))
return FALSE
var/turf/teleport_target = pick(teleport_potential)
- forceMove(teleport_target)
+ if(breach_type != BREACH_MINING)
+ forceMove(teleport_target)
playsound(get_turf(src), 'sound/abnormalities/blackswan/sis_transformation.ogg', 30, 0, 4)
return
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/contract.dm b/code/modules/mob/living/simple_animal/abnormality/waw/contract.dm
index 37200420daf4..ea28d8dcb9d8 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/contract.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/contract.dm
@@ -52,6 +52,10 @@
var/list/just_havers = list()
var/list/spawnables = list()
var/total_per_contract = 4
+ var/breaching
+ var/summon_list = list()
+ var/summon_cooldown
+ var/summon_cooldown_time = 60 SECONDS
/mob/living/simple_animal/hostile/abnormality/contract/Initialize()
. = ..()
@@ -65,6 +69,16 @@
if((initial(abno.threat_level)) <= WAW_LEVEL)
spawnables += abno
+/mob/living/simple_animal/hostile/abnormality/contract/Life()
+ . = ..()
+ if(!breaching)
+ return
+ if(LAZYLEN(summon_list) > 4)
+ return
+ if((summon_cooldown < world.time) && !(status_flags & GODMODE))
+ Summon()
+ summon_cooldown = world.time + summon_cooldown_time
+
/mob/living/simple_animal/hostile/abnormality/contract/WorkChance(mob/living/carbon/human/user, chance, work_type)
. = chance
if(!(user in total_havers))
@@ -147,8 +161,17 @@
//Meltdown
/mob/living/simple_animal/hostile/abnormality/contract/ZeroQliphoth(mob/living/carbon/human/user)
+ Summon()
+ datum_reference.qliphoth_change(2)
+
+/mob/living/simple_animal/hostile/abnormality/contract/BreachEffect(mob/living/carbon/human/user, breach_type)//causes a runtime
+ if(breach_type == BREACH_MINING)
+ breaching = TRUE
+ ..()
+
+/mob/living/simple_animal/hostile/abnormality/contract/proc/Summon(mob/living/carbon/human/user)
// Don't need to lazylen this. If this is empty there is a SERIOUS PROBLEM.
- var/mob/living/simple_animal/hostile/abnormality/spawning = pick(spawnables)
+ var/mob/living/simple_animal/hostile/abnormality/spawning = pick(spawnables)
var/mob/living/simple_animal/hostile/abnormality/spawned = new spawning(get_turf(src))
spawned.BreachEffect()
spawned.color = "#000000" //Make it black to look cool
@@ -156,7 +179,7 @@
spawned.desc = "What is that thing?"
spawned.faction = list("hostile")
spawned.core_enabled = FALSE
- datum_reference.qliphoth_change(2)
+ summon_list += spawned
/* Work effects */
/mob/living/simple_animal/hostile/abnormality/contract/SuccessEffect(mob/living/carbon/human/user, work_type, pe)
@@ -167,7 +190,6 @@
work_damage_amount = initial(work_damage_amount)
return
-
/mob/living/simple_animal/hostile/abnormality/contract/NeutralEffect(mob/living/carbon/human/user, work_type, pe)
. = ..()
NewContract(user, work_type)
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/ebony_queen.dm b/code/modules/mob/living/simple_animal/abnormality/waw/ebony_queen.dm
index bc857687fa23..6f88f1ab7634 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/ebony_queen.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/ebony_queen.dm
@@ -141,7 +141,8 @@
/mob/living/simple_animal/hostile/abnormality/ebony_queen/BreachEffect(mob/living/carbon/human/user, breach_type)
. = ..()
- addtimer(CALLBACK(src, PROC_REF(TryTeleport)), 5)
+ if(breach_type != BREACH_MINING)
+ addtimer(CALLBACK(src, PROC_REF(TryTeleport)), 5)
/mob/living/simple_animal/hostile/abnormality/ebony_queen/Move()
if(!can_act)
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/hatred_queen.dm b/code/modules/mob/living/simple_animal/abnormality/waw/hatred_queen.dm
index d9308962749d..64bb9d08a092 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/hatred_queen.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/hatred_queen.dm
@@ -693,6 +693,8 @@
return ..()
/mob/living/simple_animal/hostile/abnormality/hatred_queen/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ friendly = FALSE
death_counter = 0
if(friendly)
friendly = TRUE
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/luna.dm b/code/modules/mob/living/simple_animal/abnormality/waw/luna.dm
index 69e549cfa40f..ce12a31beecc 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/luna.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/luna.dm
@@ -6,8 +6,8 @@
icon = 'ModularTegustation/Teguicons/96x48.dmi'
icon_state = "dellaluna"
portrait = "luna"
- maxHealth = 400
- health = 400
+ maxHealth = 4000
+ health = 4000
damage_coeff = list(RED_DAMAGE = 1.2, WHITE_DAMAGE = 0, BLACK_DAMAGE = 1, PALE_DAMAGE = 2)
start_qliphoth = 3
threat_level = WAW_LEVEL
@@ -50,6 +50,17 @@
var/breached_monster
var/killspawn
+/mob/living/simple_animal/hostile/abnormality/luna/Move()
+ return FALSE
+
+/mob/living/simple_animal/hostile/abnormality/luna/CanAttack(atom/the_target)
+ return FALSE
+
+/mob/living/simple_animal/hostile/abnormality/luna/death(gibbed)
+ if(breached_monster)
+ qdel(breached_monster)
+ ..()
+
/mob/living/simple_animal/hostile/abnormality/luna/NeutralEffect(mob/living/carbon/human/user, work_type, pe)
. = ..()
if(prob(50))
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/my_form_empties.dm b/code/modules/mob/living/simple_animal/abnormality/waw/my_form_empties.dm
index 7e7cd7e3da92..5ad97db4a3fb 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/my_form_empties.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/my_form_empties.dm
@@ -178,7 +178,8 @@ But, you feel that whatever it is, is not a joyous thing."
var/turf/T = pick(GLOB.department_centers)
icon_state = icon_living
soundloop.start()
- forceMove(T)
+ if(breach_type != BREACH_MINING)
+ forceMove(T)
for(var/i = 1, i <= minion_amount ,i++)
var/karma_vis = new /obj/effect/karma_halo
var/picked = pick(pick(possible_minion_list))
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/pygmalion.dm b/code/modules/mob/living/simple_animal/abnormality/waw/pygmalion.dm
index b09f01c02142..90c976b9b969 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/pygmalion.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/pygmalion.dm
@@ -165,7 +165,7 @@
if(client)
to_chat(src, span_userdanger("The sculptor is in danger. It is now your duty to protect them!"))
- threat_level = TETH_LEVEL
+ fear_level = TETH_LEVEL
var/datum/attribute/user_attribute = sculptor.attributes[PRUDENCE_ATTRIBUTE]
var/user_attribute_level = max(1, user_attribute.level)
if (user_attribute_level > PRUDENCE_CAP)
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/rose_sign.dm b/code/modules/mob/living/simple_animal/abnormality/waw/rose_sign.dm
index c0ec8662ac94..257a79d26f5c 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/rose_sign.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/rose_sign.dm
@@ -55,6 +55,7 @@
var/list/work_roses = list()
var/list/work_damages = list()
var/list/summoned_roses = list()
+ var/rose_type = /mob/living/simple_animal/hostile/rose_summoned
var/rose_max = 4
var/rose_cooldown
var/rose_cooldown_time = 160 SECONDS
@@ -204,7 +205,10 @@
work_roses -= R
qdel(R)
var/turf/T = pick(GLOB.department_centers)
- forceMove(T)
+ if(breach_type != BREACH_MINING)//TODO: create attacking roses for this breach type
+ forceMove(T)
+ else
+ rose_type = /mob/living/simple_animal/hostile/rose_summoned/combat
/mob/living/simple_animal/hostile/abnormality/rose_sign/proc/PickTargets()//this is called by life()
rose_cooldown = world.time + rose_cooldown_time
@@ -227,11 +231,14 @@
sound_to_playing_players_on_level("sound/abnormalities/rosesign/rose_summon.ogg", 100, zlevel = z)
/mob/living/simple_animal/hostile/abnormality/rose_sign/proc/SpawnBreachRose(mob/living/carbon/human/target, turf/T)
+ if(rose_type == /mob/living/simple_animal/hostile/rose_summoned/combat)//during a mining breach, these are spawned around players
+ T = get_ranged_target_turf(get_turf(target), pick(GLOB.alldirs), 1)
if(locate(/mob/living/simple_animal/hostile/rose_summoned) in get_turf(T))//Needs to be tested in a multiplayer environment
T = get_ranged_target_turf(T, pick(GLOB.alldirs), 1)//This will move the target's turf to an adjacent one, preventing stacking and visual clutter to some degree.
var/list/flower_damtype = list()
var/damtype
- var/mob/living/simple_animal/hostile/rose_summoned/R = new(T)//Spawns the rose
+ var/mob/living/simple_animal/hostile/rose_summoned/R
+ R = new rose_type(T)//Spawns the rose
summoned_roses += R
for(var/obj/item/W in target.held_items + target.get_equipped_items())//Searches the human for any E.G.O and adds them to a list.
if(is_ego_melee_weapon(W)) //FIXME!!!! The above line doesn't actually check suit storage slots, could be more efficient too
@@ -338,6 +345,7 @@
pull_force = INFINITY
generic_canpass = FALSE
movement_type = PHASING | FLYING
+ damtype = BLACK_DAMAGE
var/root_damage = 30 //Black Damage
layer = POINT_LAYER//should always be visible.
@@ -351,7 +359,7 @@
for(var/turf/T in view(0, target_turf))
new /obj/effect/temp_visual/thornspike(T)
for(var/mob/living/L in T)
- L.deal_damage(root_damage, BLACK_DAMAGE)
+ L.deal_damage(root_damage, damtype)
if(L.stat == DEAD)
if(L.has_status_effect(/datum/status_effect/stacking/crownthorns))//Stops a second crucifix from appearing
L.remove_status_effect(STATUS_EFFECT_THORNS)
@@ -362,6 +370,15 @@
N.buckle_mob(L)
qdel(src)
+/obj/effect/roseRoot/red
+ damtype = RED_DAMAGE
+
+/obj/effect/roseRoot/white
+ damtype = WHITE_DAMAGE
+
+/obj/effect/roseRoot/pale
+ damtype = PALE_DAMAGE
+
//***Breach Roses***//
/mob/living/simple_animal/hostile/rose_summoned
@@ -374,7 +391,7 @@
maxHealth = 500
health = 500
damage_coeff = list(RED_DAMAGE = 0.5, WHITE_DAMAGE = 0.5, BLACK_DAMAGE = 0.5, PALE_DAMAGE = 0.5)
- del_on_death = FALSE
+ del_on_death = TRUE
var/flower_damage_type
var/mob/living/simple_animal/hostile/abnormality/rose_sign/master
var/mob/living/status_target
@@ -401,7 +418,7 @@
/mob/living/simple_animal/hostile/rose_summoned/CanAttack(atom/the_target)
return FALSE
-/mob/living/simple_animal/hostile/rose_summoned/death()
+/mob/living/simple_animal/hostile/rose_summoned/Destroy()
if(!killed || !status_target)
return ..()
if(flower_damage_type && master)
@@ -409,11 +426,44 @@
master.ChangeResistance(flower_damage_type, (master.damage_coeff.getCoeff(flower_damage_type) + 0.3), update = TRUE)
if(status_target.has_status_effect(/datum/status_effect/stacking/crownthorns))
status_target.remove_status_effect(STATUS_EFFECT_THORNS)
- density = FALSE
- animate(src, alpha = 0, time = 10 SECONDS)
- QDEL_IN(src, 10 SECONDS)
..()
+/mob/living/simple_animal/hostile/rose_summoned/combat//mining breach variant
+ maxHealth = 1000
+ health = 1000
+ ranged = TRUE
+ var/root_type = /obj/effect/roseRoot
+ var/can_act = TRUE
+
+/mob/living/simple_animal/hostile/rose_summoned/combat/CanAttack(atom/the_target)
+ if(prob(30))
+ return OpenFire()
+
+/mob/living/simple_animal/hostile/rose_summoned/combat/OpenFire()
+ if(!can_act)
+ return
+ rootBarrage(target)//Ebony queen-style basic attack
+
+/mob/living/simple_animal/hostile/rose_summoned/combat/PickColor(picked_color)
+ ..()
+ switch(picked_color)
+ if(RED_DAMAGE)
+ root_type = /obj/effect/roseRoot/red
+ if(WHITE_DAMAGE)
+ root_type = /obj/effect/roseRoot/white
+ if(PALE_DAMAGE)
+ root_type = /obj/effect/roseRoot/pale
+
+/mob/living/simple_animal/hostile/rose_summoned/combat/proc/rootBarrage(target, picked_color)//Ebony queen's basic attack, fired at a low rate.
+ can_act = FALSE
+ playsound(get_turf(target), 'sound/creatures/venus_trap_hurt.ogg', 75, 0, 5)
+ SLEEP_CHECK_DEATH(3)
+ var/turf/target_turf = get_turf(target)
+ for(var/turf/T in view(0, target_turf))
+ new root_type(T)
+ SLEEP_CHECK_DEATH(3)
+ can_act = TRUE
+
//***Work-Based Roses***//
/obj/structure/rose_work
gender = NEUTER
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/screenwriter.dm b/code/modules/mob/living/simple_animal/abnormality/waw/screenwriter.dm
index b5db3f472314..acd04cfa469d 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/screenwriter.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/screenwriter.dm
@@ -11,6 +11,9 @@ Defeating the murderer also surpresses the abnormality.
icon = 'ModularTegustation/Teguicons/32x32.dmi'
icon_state = "screenwriter"
portrait = "screenwriter"
+ maxHealth = 4000
+ health = 4000
+ damage_coeff = list(RED_DAMAGE = 1.3, WHITE_DAMAGE = 0.5, BLACK_DAMAGE = 1.3, PALE_DAMAGE = 1.5)
faction = list("hostile")
threat_level = WAW_LEVEL
start_qliphoth = 2
@@ -56,6 +59,18 @@ Defeating the murderer also surpresses the abnormality.
preferred_work_type = pick(work_chances)
SpawnIcon()
+/mob/living/simple_animal/hostile/abnormality/screenwriter/Move()
+ return FALSE
+
+/mob/living/simple_animal/hostile/abnormality/screenwriter/CanAttack(atom/the_target)
+ return FALSE
+
+/mob/living/simple_animal/hostile/abnormality/screenwriter/Destroy()
+ if(A)
+ A.death()
+ EndScenario()
+ ..()
+
//Work stuff
/mob/living/simple_animal/hostile/abnormality/screenwriter/AttemptWork(mob/living/carbon/human/user, work_type)
if(A)
@@ -110,6 +125,10 @@ Defeating the murderer also surpresses the abnormality.
MeltdownEffect()
return
+/mob/living/simple_animal/hostile/abnormality/screenwriter/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ MeltdownEffect()
+
/mob/living/simple_animal/hostile/abnormality/screenwriter/proc/MeltdownEffect()
var/turf/actor_location = pick(GLOB.department_centers) //Spawn the murderer
A = new (actor_location)
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/shrimp.dm b/code/modules/mob/living/simple_animal/abnormality/waw/shrimp.dm
index 48b06b5b3e7a..810aafacf7ff 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/shrimp.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/shrimp.dm
@@ -118,6 +118,11 @@
datum_reference.qliphoth_change(1)
return
+/mob/living/simple_animal/hostile/abnormality/shrimp_exec/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ pissed()
+ addtimer(CALLBACK(src, PROC_REF(pissed)), 20 SECONDS)
+
/mob/living/simple_animal/hostile/abnormality/shrimp_exec/AttemptWork(mob/living/carbon/human/user, work_type)
if(work_type == liked || !liked)
happy = TRUE
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/snow_whites_apple.dm b/code/modules/mob/living/simple_animal/abnormality/waw/snow_whites_apple.dm
index a059d5072b52..ffed8e347bf1 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/snow_whites_apple.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/snow_whites_apple.dm
@@ -77,6 +77,7 @@
var/hedge_cooldown_delay = FLORAL_BARRIER_COOLDOWN
var/teleport_cooldown = 0
var/teleport_cooldown_delay = 60 SECONDS
+ var/can_teleport = TRUE
//Spell automatically given to the abnormality.
var/obj/effect/proc_holder/spell/pointed/apple_barrier/barrier_spell
//All iterations share this list between eachother.
@@ -96,6 +97,8 @@
/mob/living/simple_animal/hostile/abnormality/snow_whites_apple/BreachEffect(mob/living/carbon/human/user, breach_type)
. = ..()
update_icon()
+ if(breach_type == BREACH_MINING)//TODO: create attacking roses for this breach type
+ can_teleport = FALSE
/mob/living/simple_animal/hostile/abnormality/snow_whites_apple/Initialize()
. = ..()
@@ -198,6 +201,8 @@
dir = 2
if(teleport_cooldown > world.time)
return FALSE
+ if(!can_teleport)
+ return FALSE
teleport_cooldown = world.time + teleport_cooldown_delay
var/list/teleport_potential = TeleportList()
if(!LAZYLEN(teleport_potential))
diff --git a/code/modules/mob/living/simple_animal/abnormality/zayin/blubbering_toad.dm b/code/modules/mob/living/simple_animal/abnormality/zayin/blubbering_toad.dm
index 91b51986a08d..9cd839994012 100644
--- a/code/modules/mob/living/simple_animal/abnormality/zayin/blubbering_toad.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/zayin/blubbering_toad.dm
@@ -116,8 +116,15 @@
//Attack or approach it directly and it attacks you!
/mob/living/simple_animal/hostile/abnormality/blubbering_toad/BreachEffect(mob/living/user, breach_type = BREACH_NORMAL)
- if(breach_type == BREACH_PINK)
+ if(breach_type == BREACH_PINK || breach_type == BREACH_MINING)
persistant = TRUE
+ if(breach_type == BREACH_MINING)//nerfed to a ZAYIN statline since this is something you'll typically fight roundstart
+ name = "Weakened " + name
+ maxHealth = 400
+ melee_damage_lower = 9
+ melee_damage_upper = 15
+ tongue_damage = 10
+ broken = TRUE
SetIdiot(user)
return ..()
diff --git a/code/modules/mob/living/simple_animal/abnormality/zayin/bottle.dm b/code/modules/mob/living/simple_animal/abnormality/zayin/bottle.dm
index f35de3ec6a90..78586e1f2a1e 100644
--- a/code/modules/mob/living/simple_animal/abnormality/zayin/bottle.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/zayin/bottle.dm
@@ -189,12 +189,15 @@
// Pink Midnight Breach
/mob/living/simple_animal/hostile/abnormality/bottle/BreachEffect(mob/living/carbon/human/user, breach_type)
- if(breach_type == BREACH_PINK)
+ if(breach_type == BREACH_PINK || breach_type == BREACH_MINING)
ADD_TRAIT(src, TRAIT_MOVE_FLYING, INNATE_TRAIT)
COOLDOWN_START(src, speak_damage_aura, speak_cooldown_time)
icon_state = "bottle_breach"
desc = "A floating bottle, leaking tears.\nYou can use an empty hand to drink from it."
can_breach = TRUE
+ if(breach_type == BREACH_MINING)
+ speak_damage = 0
+ speak_cooldown_time = 15 SECONDS
return ..()
/mob/living/simple_animal/hostile/abnormality/bottle/attack_hand(mob/living/carbon/human/M)
diff --git a/code/modules/mob/living/simple_animal/abnormality/zayin/fairy_festival.dm b/code/modules/mob/living/simple_animal/abnormality/zayin/fairy_festival.dm
index 9b75c676af9a..102d5334bc20 100644
--- a/code/modules/mob/living/simple_animal/abnormality/zayin/fairy_festival.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/zayin/fairy_festival.dm
@@ -7,6 +7,10 @@
portrait = "fairy_festival"
maxHealth = 83
health = 83
+ damage_coeff = list(RED_DAMAGE = 1, WHITE_DAMAGE = 1.2, BLACK_DAMAGE = 1.3, PALE_DAMAGE = 2)
+ melee_damage_lower = 8
+ melee_damage_upper = 15
+ attack_sound = 'sound/abnormalities/fairyfestival/fairyqueen_hit.ogg'
is_flying_animal = TRUE
threat_level = ZAYIN_LEVEL
work_chances = list(
@@ -118,6 +122,13 @@
if(breach_type == BREACH_PINK)
SummonGuys()
addtimer(CALLBACK(src, PROC_REF(SummonGuys)), 20 SECONDS)
+ if(breach_type == BREACH_MINING)
+ icon = 'ModularTegustation/Teguicons/96x48.dmi'
+ icon_state = "fairy_queen"
+ pixel_x = -32
+ maxHealth = 500
+ playsound(get_turf(src), "sound/abnormalities/seasons/fall_change.ogg", 100, FALSE)
+ playsound(get_turf(src), "sound/abnormalities/fairyfestival/fairyqueen_growl.ogg", 100, FALSE)
return ..()
/mob/living/simple_animal/hostile/abnormality/fairy_festival/proc/SummonGuys()
diff --git a/code/modules/mob/living/simple_animal/abnormality/zayin/one_sin.dm b/code/modules/mob/living/simple_animal/abnormality/zayin/one_sin.dm
index 74c4c9182002..8160bb4e7fea 100644
--- a/code/modules/mob/living/simple_animal/abnormality/zayin/one_sin.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/zayin/one_sin.dm
@@ -7,6 +7,13 @@
portrait = "one_sin"
maxHealth = 777
health = 777
+ damage_coeff = list(RED_DAMAGE = 1.5, WHITE_DAMAGE = 1, BLACK_DAMAGE = 1, PALE_DAMAGE = 2)
+ melee_damage_lower = 8
+ melee_damage_upper = 15
+ melee_damage_type = WHITE_DAMAGE
+ attack_sound = 'sound/abnormalities/onesin/onesin_attack.ogg'
+ attack_verb_continuous = "smites"
+ attack_verb_simple = "smite"
is_flying_animal = TRUE
threat_level = ZAYIN_LEVEL
work_chances = list(
@@ -131,8 +138,16 @@
H.adjustSanityLoss(-H.maxSanity * heal_factor)
/mob/living/simple_animal/hostile/abnormality/onesin/BreachEffect(mob/living/carbon/human/user, breach_type)
+ if(breach_type == BREACH_MINING)
+ update_icon()
+ ..()
+ return
return FALSE // If someone wants him to breach for SOME REASON in the future, then exclude breach_type == BREACH_PINK
+/mob/living/simple_animal/hostile/abnormality/onesin/AttackingTarget()
+ ..()
+ new /obj/effect/temp_visual/onesin_punishment(get_turf(target))
+
/datum/reagent/abnormality/onesin
name = "Holy Light"
description = "It's calming, even if you can't quite look at it straight."
diff --git a/code/modules/mob/living/simple_animal/abnormality/zayin/quiet_day.dm b/code/modules/mob/living/simple_animal/abnormality/zayin/quiet_day.dm
index 0549c06acd1e..8dc4c731b3fd 100644
--- a/code/modules/mob/living/simple_animal/abnormality/zayin/quiet_day.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/zayin/quiet_day.dm
@@ -228,7 +228,7 @@
return FALSE
/mob/living/simple_animal/hostile/abnormality/quiet_day/BreachEffect(mob/living/carbon/human/user, breach_type)
- if(breach_type == BREACH_PINK)
+ if(breach_type == BREACH_PINK || breach_type == BREACH_MINING)
AbnoRadio()
Ramble()
can_breach = TRUE
diff --git a/code/modules/mob/living/simple_animal/distortion/monolith.dm b/code/modules/mob/living/simple_animal/distortion/monolith.dm
index f746472ce6f3..59b2422631d1 100644
--- a/code/modules/mob/living/simple_animal/distortion/monolith.dm
+++ b/code/modules/mob/living/simple_animal/distortion/monolith.dm
@@ -133,7 +133,7 @@
var/mob/living/simple_animal/hostile/distortion/D = target
if(D.monolith_abnormality)
var/mob/living/simple_animal/hostile/abnormality/myAbno = new D.monolith_abnormality(get_turf(target))
- myAbno.BreachEffect()
+ myAbno.BreachEffect(null, BREACH_MINING)
qdel(target)
return TRUE
return FALSE
diff --git a/lobotomy-corp13.dme b/lobotomy-corp13.dme
index ebe6abe2945d..33e9a295f795 100644
--- a/lobotomy-corp13.dme
+++ b/lobotomy-corp13.dme
@@ -2373,8 +2373,8 @@
#include "code\modules\jobs\job_types\city\civilian.dm"
#include "code\modules\jobs\job_types\city\doctor.dm"
#include "code\modules\jobs\job_types\city\HHPP.dm"
-#include "code\modules\jobs\job_types\city\rat.dm"
#include "code\modules\jobs\job_types\city\prosthetic.dm"
+#include "code\modules\jobs\job_types\city\rat.dm"
#include "code\modules\jobs\job_types\city\workshop.dm"
#include "code\modules\jobs\job_types\city\fixer\east.dm"
#include "code\modules\jobs\job_types\city\fixer\north.dm"
diff --git a/sound/abnormalities/fairyfestival/fairyqueen_growl.ogg b/sound/abnormalities/fairyfestival/fairyqueen_growl.ogg
new file mode 100644
index 000000000000..ff83bdba6c5b
Binary files /dev/null and b/sound/abnormalities/fairyfestival/fairyqueen_growl.ogg differ
diff --git a/sound/abnormalities/fairyfestival/fairyqueen_hit.ogg b/sound/abnormalities/fairyfestival/fairyqueen_hit.ogg
new file mode 100644
index 000000000000..f359a470f88e
Binary files /dev/null and b/sound/abnormalities/fairyfestival/fairyqueen_hit.ogg differ
diff --git a/sound/abnormalities/onesin/onesin_attack.ogg b/sound/abnormalities/onesin/onesin_attack.ogg
new file mode 100644
index 000000000000..e3d9a2843dbd
Binary files /dev/null and b/sound/abnormalities/onesin/onesin_attack.ogg differ