diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm
index f960a7443ee..b3b3157c391 100644
--- a/code/game/objects/structures/spawner.dm
+++ b/code/game/objects/structures/spawner.dm
@@ -85,4 +85,16 @@
/obj/structure/spawner/mining/basilisk
name = "basilisk den"
desc = "A den housing a nest of basilisks, bring a coat."
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk)
\ No newline at end of file
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk)
+
+/obj/structure/spawner/headcrab
+ name = "headcrab nest"
+ desc = "A living nest for headcrabs. It is moving ominously."
+ icon_state = "headcrab_nest"
+ icon = 'icons/mob/headcrab.dmi'
+ max_integrity = 200
+ max_mobs = 15
+ spawn_time = 600
+ mob_types = list(/mob/living/simple_animal/hostile/headcrab, /mob/living/simple_animal/hostile/headcrab/fast, /mob/living/simple_animal/hostile/headcrab/poison)
+ spawn_text = "crawls out of"
+ faction = list("hostile")
\ No newline at end of file
diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm
index 3f86b88924c..1c99d2d1bc0 100644
--- a/code/modules/events/event_container.dm
+++ b/code/modules/events/event_container.dm
@@ -181,7 +181,8 @@ var/list/event_last_fired = list()
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Revenant", /datum/event/revenant, 150),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Swarmer Spawn", /datum/event/spawn_swarmer, 150, is_one_shot = 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 40, is_one_shot = 1),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disease Outbreak", /datum/event/disease_outbreak, 0, list(ASSIGNMENT_MEDICAL = 150), 1)
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disease Outbreak", /datum/event/disease_outbreak, 0, list(ASSIGNMENT_MEDICAL = 150), 1),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Headcrabs", /datum/event/headcrabs, 0, list(ASSIGNMENT_SECURITY = 20))
)
/datum/event_container/major
diff --git a/code/modules/events/headcrabs.dm b/code/modules/events/headcrabs.dm
index ced8562c96c..b1eef858d7e 100644
--- a/code/modules/events/headcrabs.dm
+++ b/code/modules/events/headcrabs.dm
@@ -1,114 +1,29 @@
-#define LOC_ATMOS_CONTROL 0
-#define LOC_FPMAINT 1
-#define LOC_FPMAINT2 2
-#define LOC_FSMAINT 3
-#define LOC_FSMAINT2 4
-#define LOC_ASMAINT 5
-#define LOC_ASMAINT2 6
-#define LOC_APMAINT 7
-#define LOC_MAINTCENTRAL 8
-#define LOC_FORE 9
-#define LOC_STARBOARD 10
-#define LOC_PORT 11
-#define LOC_AFT 12
-#define LOC_STORAGE 13
-#define LOC_DISPOSAL 14
-#define LOC_GENETICS 15
-#define LOC_ELECTRICAL 16
-#define LOC_ABANDONEDBAR 17
-#define LOC_ELECTRICAL_SHOP 18
-#define LOC_GAMBLING_DEN 19
-
#define HEADCRAB_NORMAL 0
#define HEADCRAB_FASTMIX 1
#define HEADCRAB_FAST 2
#define HEADCRAB_POISONMIX 3
#define HEADCRAB_POISON 4
-/*#define HEADCRAB_CLOWN 5 */ //Planned for the future. maybe
+#define HEADCRAB_SPAWNER 5
/datum/event/headcrabs
announceWhen = 10
endWhen = 11
- var/location
var/locstring
- var/headcrab
+ var/headcrab_type
/datum/event/headcrabs/start()
-
- location = rand(0,19)
+ var/list/availableareas = list()
+ for(var/area/maintenance/A in world)
+ availableareas += A
+ var/area/randomarea = pick(availableareas)
var/list/turf/simulated/floor/turfs = list()
- var/spawn_area_type
- switch(location)
- if(LOC_ATMOS_CONTROL)
- spawn_area_type = /area/maintenance/atmos_control
- locstring = "Atmospherics Maintenance"
- if(LOC_FPMAINT)
- spawn_area_type = /area/maintenance/fpmaint
- locstring = "EVA Maintenance"
- if(LOC_FPMAINT2)
- spawn_area_type = /area/maintenance/fpmaint2
- locstring = "Arrivals North Maintenance"
- if(LOC_FSMAINT)
- spawn_area_type = /area/maintenance/fsmaint
- locstring = "Dormitory Maintenance"
- if(LOC_FSMAINT2)
- spawn_area_type = /area/maintenance/fsmaint2
- locstring = "Bar Maintenance"
- if(LOC_ASMAINT)
- spawn_area_type = /area/maintenance/asmaint
- locstring = "Medbay Maintenance"
- if(LOC_ASMAINT2)
- spawn_area_type = /area/maintenance/asmaint2
- locstring = "Science Maintenance"
- if(LOC_APMAINT)
- spawn_area_type = /area/maintenance/apmaint
- locstring = "Cargo Maintenance"
- if(LOC_MAINTCENTRAL)
- spawn_area_type = /area/maintenance/maintcentral
- locstring = "Bridge Maintenance"
- if(LOC_FORE)
- spawn_area_type = /area/maintenance/fore
- locstring = "Fore Maintenance"
- if(LOC_STARBOARD)
- spawn_area_type = /area/maintenance/starboard
- locstring = "Starboard Maintenance"
- if(LOC_PORT)
- spawn_area_type = /area/maintenance/port
- locstring = "Locker Room Maintenance"
- if(LOC_AFT)
- spawn_area_type = /area/maintenance/aft
- locstring = "Engineering Maintenance"
- if(LOC_STORAGE)
- spawn_area_type = /area/maintenance/storage
- locstring = "Atmospherics Maintenance"
- if(LOC_DISPOSAL)
- spawn_area_type = /area/maintenance/disposal
- locstring = "Waste Disposal"
- if(LOC_GENETICS)
- spawn_area_type = /area/maintenance/genetics
- locstring = "Genetics Maintenance"
- if(LOC_ELECTRICAL)
- spawn_area_type = /area/maintenance/electrical
- locstring = "Electrical Maintenance"
- if(LOC_ABANDONEDBAR)
- spawn_area_type = /area/maintenance/abandonedbar
- locstring = "Maintenance Bar"
- if(LOC_ELECTRICAL_SHOP)
- spawn_area_type = /area/maintenance/electrical_shop
- locstring ="Electronics Den"
- if(LOC_GAMBLING_DEN)
- spawn_area_type = /area/maintenance/gambling_den
- locstring = "Gambling Den"
- for(var/areapath in typesof(spawn_area_type))
- var/area/A = locate(areapath)
- for(var/turf/simulated/floor/F in A.contents)
- if(turf_clear(F))
- turfs += F
-
+ for(var/turf/simulated/floor/F in randomarea)
+ if(turf_clear(F))
+ turfs += F
var/list/spawn_types = list()
var/max_number
- headcrab = rand(0, 4) //rand(0,x) for the future
- switch(headcrab) //Switch is for the future
+ headcrab_type = rand(0, 5)
+ switch(headcrab_type)
if(HEADCRAB_NORMAL)
spawn_types = list(/mob/living/simple_animal/hostile/headcrab)
max_number = 6
@@ -124,9 +39,13 @@
if(HEADCRAB_POISON)
spawn_types = list(/mob/living/simple_animal/hostile/headcrab/poison)
max_number = 3
+ if(HEADCRAB_SPAWNER)
+ spawn_types = list(/obj/structure/spawner/headcrab)
+ max_number = 2
var/num = rand(2,max_number)
+
while(turfs.len > 0 && num > 0)
var/turf/simulated/floor/T = pick(turfs)
turfs.Remove(T)
@@ -136,31 +55,11 @@
/datum/event/headcrabs/announce()
- event_announcement.Announce("Bioscans indicate that creatures have been breeding in [locstring]. Clear them out, before this starts to affect productivity", "Lifesign Alert")
-
-#undef LOC_ATMOS_CONTROL
-#undef LOC_FPMAINT
-#undef LOC_FPMAINT2
-#undef LOC_FSMAINT
-#undef LOC_FSMAINT2
-#undef LOC_ASMAINT
-#undef LOC_ASMAINT2
-#undef LOC_APMAINT
-#undef LOC_MAINTCENTRAL
-#undef LOC_FORE
-#undef LOC_STARBOARD
-#undef LOC_PORT
-#undef LOC_AFT
-#undef LOC_STORAGE
-#undef LOC_DISPOSAL
-#undef LOC_GENETICS
-#undef LOC_ELECTRICAL
-#undef LOC_ABANDONEDBAR
-#undef LOC_ELECTRICAL_SHOP
-#undef LOC_GAMBLING_DEN
+ event_announcement.Announce("Bioscans indicate that headcrabs have been breeding on the station. Clear them out, before this starts to affect productivity", "Lifesign Alert")
#undef HEADCRAB_NORMAL
#undef HEADCRAB_FASTMIX
#undef HEADCRAB_FAST
#undef HEADCRAB_POISONMIX
-#undef HEADCRAB_POISON
\ No newline at end of file
+#undef HEADCRAB_POISON
+#undef HEADCRAB_SPAWNER
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
index 71356b7c52c..e48d980c2a4 100644
--- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm
+++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
@@ -5,8 +5,9 @@
icon_state = "headcrab"
icon_living = "headcrab"
icon_dead = "headcrab_dead"
- health = 40
- maxHealth = 40
+ health = 60
+ maxHealth = 60
+ dodging = 1
melee_damage_lower = 5
melee_damage_upper = 10
ranged = 1
@@ -18,7 +19,8 @@
attack_sound = 'sound/creatures/headcrab_attack.ogg'
speak_emote = list("hisses")
var/is_zombie = 0
- stat_attack = DEAD //so they continue to attack when they are on the ground.
+ stat_attack = DEAD //so they continue to attack when they are on the ground.
+ robust_searching = 1
var/host_species = ""
var/list/human_overlays = list()
@@ -28,6 +30,17 @@
if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD))
Zombify(H)
break
+ var/cycles = 4
+ if(cycles >= 4)
+ for(var/mob/living/simple_animal/K in oview(src, 1)) //Only for corpse right next to/on same tile
+ if(K.stat == DEAD || (!K.check_death_method() && K.health <= HEALTH_THRESHOLD_DEAD))
+ visible_message("[src] consumes [target] whole!")
+ if(health < maxHealth)
+ health += 10
+ qdel(K)
+ break
+ cycles = 0
+ cycles++
..()
/mob/living/simple_animal/hostile/headcrab/OpenFire(atom/A)
@@ -51,7 +64,7 @@
var/obj/item/clothing/suit/armor/A = H.wear_suit
if(A.armor && A.armor["melee"])
maxHealth += A.armor["melee"] //That zombie's got armor, I want armor!
- maxHealth += 50
+ maxHealth += 200
health = maxHealth
name = "zombie"
desc = "A corpse animated by the alien being on its head."
@@ -114,8 +127,8 @@
icon_state = "fast_headcrab"
icon_living = "fast_headcrab"
icon_dead = "fast_headcrab_dead"
- health = 30
- maxHealth = 30
+ health = 40
+ maxHealth = 40
ranged_cooldown_time = 30
jumpdistance = 8
jumpspeed = 2
@@ -144,11 +157,13 @@
icon_state = "poison_headcrab"
icon_living = "poison_headcrab"
icon_dead = "poison_headcrab_dead"
- health = 60
- maxHealth = 60
+ health = 80
+ maxHealth = 80
ranged_cooldown_time = 50
jumpdistance = 3
jumpspeed = 1
+ melee_damage_lower = 8
+ melee_damage_upper = 20
attack_sound = 'sound/creatures/ph_scream1.ogg'
speak_emote = list("screech")
@@ -167,6 +182,10 @@
/mob/living/simple_animal/hostile/headcrab/poison/AttackingTarget()
. = ..()
- var/mob/living/carbon/C = target
- if(C.can_inject(null, FALSE, "head", FALSE))
- C.reagents.add_reagent("lsd", 5)
+ if(iscarbon(target) && target.reagents)
+ var/inject_target = pick("chest", "head")
+ var/mob/living/carbon/C = target
+ if(C.stunned || C.can_inject(null, FALSE, inject_target, FALSE))
+ if(C.eye_blurry < 60)
+ C.AdjustEyeBlurry(10)
+ visible_message("[src] buries its fangs deep into the [inject_target] of [target]!")
diff --git a/icons/mob/headcrab.dmi b/icons/mob/headcrab.dmi
index b308179b45f..a1081b39835 100644
Binary files a/icons/mob/headcrab.dmi and b/icons/mob/headcrab.dmi differ