diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 1b3318acbb8..d26b885fb96 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -421,6 +421,7 @@ var/global/floorIsLava = 0
Spawn blob
Trigger an Alien infestation
Spawn an Alien silently
+ Trigger a Spider infestation
Send in a space ninja
Send in a strike team
Trigger an Carp migration
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 572d96e841a..b98ed58551c 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1959,6 +1959,11 @@
feedback_add_details("admin_secrets_fun_used","ALS")
if(aliens_allowed)
create_xeno()
+ if("spiders")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SL")
+ new /datum/event/spider_infestation
+ message_admins("[key_name_admin(usr)] has spawned spiders", 1)
if("comms_blackout")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","CB")
diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm
index 977c491d2d0..393ed9de8af 100644
--- a/code/modules/events/event_manager.dm
+++ b/code/modules/events/event_manager.dm
@@ -1,8 +1,8 @@
var/list/allEvents = typesof(/datum/event) - /datum/event
var/list/potentialRandomEvents = typesof(/datum/event) - /datum/event
-var/eventTimeLower = 9000 //15 minutes
-var/eventTimeUpper = 15000 //25 minutes
+var/eventTimeLower = 15000 //15 minutes
+var/eventTimeUpper = 30000 //30 minutes
var/scheduledEvent = null
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index 892367c4d18..57d4338c175 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -22,26 +22,37 @@
health = 40
melee_damage_lower = 1
melee_damage_upper = 5
+ var/datum/reagents/udder = null
+
+/mob/living/simple_animal/hostile/retaliate/goat/New()
+ udder = new(50)
+ udder.my_atom = src
+ ..()
/mob/living/simple_animal/hostile/retaliate/goat/Life()
- ..()
- //chance to go crazy and start wacking stuff
- if(prob(1))
- src.visible_message("\red [src] gets an evil-looking gleam in their eye.")
- faction = "hostile"
- if(faction == "hostile" && prob(10))
- faction = "neutral"
- enemies = list()
- stance = HOSTILE_STANCE_IDLE
- target_mob = null
+ . = ..()
+ if(.)//chance to go crazy and start wacking stuff
+ if(prob(1))
+ src.visible_message("\red [src] gets an evil-looking gleam in their eye.")
+ faction = "hostile"
+ if(faction == "hostile" && prob(10))
+ faction = "neutral"
+ enemies = list()
+ stance = HOSTILE_STANCE_IDLE
+ target_mob = null
+ if(stat == CONSCIOUS)
+ if(udder && prob(5))
+ udder.add_reagent("milk", rand(5, 10))
/mob/living/simple_animal/hostile/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if(istype(O, /obj/item/weapon/reagent_containers/glass))
- user.visible_message("[user] milks [src] into the [O].")
+ if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass))
+ user.visible_message("[user] milks [src] using the [O].")
var/obj/item/weapon/reagent_containers/glass/G = O
- G.reagents.add_reagent("milk",rand(7,12))
+ var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
if(G.reagents.total_volume >= G.volume)
user << "\red The [O] is full."
+ if(!transfered)
+ user << "\red The udder is dry. Wait a bit longer..."
else
..()
//cow
@@ -66,24 +77,38 @@
response_harm = "kicks the"
attacktext = "kicks"
health = 50
+ var/datum/reagents/udder = null
+
+/mob/living/simple_animal/cow/New()
+ udder = new(50)
+ udder.my_atom = src
+ ..()
/mob/living/simple_animal/cow/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if(istype(O, /obj/item/weapon/reagent_containers/glass))
- user.visible_message("[user] milks [src] into the [O].")
+ if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass))
+ user.visible_message("[user] milks [src] using the [O].")
var/obj/item/weapon/reagent_containers/glass/G = O
- G.reagents.add_reagent("milk",rand(5,10))
+ var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
if(G.reagents.total_volume >= G.volume)
user << "\red The [O] is full."
+ if(!transfered)
+ user << "\red The udder is dry. Wait a bit longer..."
else
..()
+/mob/living/simple_animal/cow/Life()
+ . = ..()
+ if(stat == CONSCIOUS)
+ if(udder && prob(5))
+ udder.add_reagent("milk", rand(5, 10))
+
/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M as mob)
if(!stat && M.a_intent == "disarm" && icon_state != icon_dead)
M.visible_message("[M] tips over [src].","You tip over [src].")
Weaken(30)
icon_state = icon_dead
spawn(rand(20,50))
- if(!stat)
+ if(!stat && M)
icon_state = icon_living
var/list/responses = list( "[src] looks at you imploringly.",
"[src] looks at you pleadingly",
@@ -104,7 +129,7 @@
speak_emote = list("cheeps")
emote_hear = list("cheeps")
emote_see = list("pecks at the ground","flaps it's tiny wings")
- speak_chance = 10
+ speak_chance = 5
turns_per_move = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 1
@@ -116,19 +141,24 @@
var/amount_grown = 0
pass_flags = PASSTABLE | PASSGRILLE
- New()
- ..()
- pixel_x = rand(-6, 6)
- pixel_y = rand(0, 10)
+/mob/living/simple_animal/chick/New()
+ ..()
+ pixel_x = rand(-6, 6)
+ pixel_y = rand(0, 10)
/mob/living/simple_animal/chick/Life()
- ..()
+ . =..()
+ if(!.)
+ return
if(!stat)
amount_grown += rand(1,2)
if(amount_grown >= 100)
new /mob/living/simple_animal/chicken(src.loc)
del(src)
+var/const/MAX_CHICKENS = 50
+var/global/chicken_count = 0
+
/mob/living/simple_animal/chicken
name = "chicken"
desc = "Hopefully the eggs are good this season."
@@ -139,7 +169,7 @@
speak_emote = list("clucks","croons")
emote_hear = list("clucks")
emote_see = list("pecks at the ground","flaps it's wings viciously")
- speak_chance = 10
+ speak_chance = 5
turns_per_move = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 2
@@ -150,26 +180,36 @@
health = 10
pass_flags = PASSTABLE
- New()
- ..()
- pixel_x = rand(-6, 6)
- pixel_y = rand(0, 10)
+/mob/living/simple_animal/chicken/New()
+ ..()
+ pixel_x = rand(-6, 6)
+ pixel_y = rand(0, 10)
+ chicken_count += 1
+
+/mob/living/simple_animal/chicken/Die()
+ ..()
+ chicken_count -= 1
/mob/living/simple_animal/chicken/Life()
- ..()
+ . =..()
+ if(!.)
+ return
if(!stat && prob(1))
visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]")
- var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(src.loc)
+ var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(get_turf(src))
E.pixel_x = rand(-6,6)
E.pixel_y = rand(-6,6)
- processing_objects.Add(E)
+ if(chicken_count < MAX_CHICKENS && prob(10))
+ processing_objects.Add(E)
-obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0
+/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0
/obj/item/weapon/reagent_containers/food/snacks/egg/process()
- amount_grown += rand(1,2)
- if(amount_grown >= 100)
- if(prob(50))
+ if(isturf(loc))
+ amount_grown += rand(1,2)
+ if(amount_grown >= 100)
visible_message("[src] hatches with a quiet cracking sound.")
- new /mob/living/simple_animal/chick(src.loc)
+ new /mob/living/simple_animal/chick(get_turf(src))
+ processing_objects.Remove(src)
+ del(src)
+ else
processing_objects.Remove(src)
- del(src)
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index c1edcdea208..bc9747a2d67 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -26,7 +26,7 @@
melee_damage_lower = 15
melee_damage_upper = 20
var/poison_per_bite = 5
- var/poison_type = "mindbreaker"
+ var/poison_type = "toxin"
faction = "spiders"
var/busy = 0
pass_flags = PASSTABLE
@@ -43,7 +43,7 @@
melee_damage_upper = 10
poison_per_bite = 10
var/atom/cocoon_target
- poison_type = "zombiepowder"
+ poison_type = "stoxin"
var/fed = 0
//hunters have the most poison and move the fastest, so they can find prey
@@ -56,7 +56,7 @@
health = 120
melee_damage_lower = 10
melee_damage_upper = 20
- poison_per_bite = 20
+ poison_per_bite = 5
/mob/living/simple_animal/hostile/giant_spider/AttackingTarget()
..()
@@ -72,8 +72,8 @@
..()
if(!stat)
if(stance == HOSTILE_STANCE_IDLE)
- //10% chance to skitter madly away
- if(!busy && prob(10))
+ //1% chance to skitter madly away
+ if(!busy && prob(1))
/*var/list/move_targets = list()
for(var/turf/T in orange(20, src))
move_targets.Add(T)*/
diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm
index cc5760ed77b..a005b4651af 100644
--- a/code/modules/reagents/Chemistry-Recipes.dm
+++ b/code/modules/reagents/Chemistry-Recipes.dm
@@ -979,6 +979,7 @@ datum
/mob/living/simple_animal/hostile/syndicate/ranged,
/mob/living/simple_animal/hostile/syndicate/ranged/space,
/mob/living/simple_animal/hostile/alien/queen/large,
+ /mob/living/simple_animal/hostile/retaliate,
/mob/living/simple_animal/hostile/retaliate/clown
)//exclusion list for things you don't want the reaction to create.
var/list/critters = typesof(/mob/living/simple_animal/hostile) - blocked // list of possible hostile mobs