Committing for Cael_Aislinn:

= Giant Spiders =
- Nurses spin webs which impede progress, bundle items and mobs up in cocoons, lay eggs to create spiderlings
- Nurses are slow and weak, but their bite has a chance to paralyse the victim
- Spiderlings skitter about and eventually grow into giant spiders. 
- Spiderlings will ventcrawl, so they can spread over the station pretty fast. 
- Hunters are fast, have decent health and the most effective poison
- Guards are medium speed but the health and direct damage
- The poison of hunters and guards can cause hallucinations if they bite you

= Farm animals =
- Cows can be milked or butchered for a large supply of meat. Sadists can also tip them over (with intent_help). 
- Goats can also be milked, but have a nasty temperament. 
- Chicks grow up to be chickens, who lay eggs and continue the cycle. But where did it start? (they're very noisy). 
- All three are orderable via QM. 

My changes:

- Added a spider infestation event.
- Optimized code with spiders and simple_animals.
- Made a /hostile/retaliate type which will only fight back when hurt. Based on Cael's code.
- Added some farm animals on the map.
- Changed events, added a setup() proc which can let you setup variables or the event. Made the event only kill itself when it has called, announce(), start() and end().
- Brainrot will only need alkysine as a cure.
- Communication blackout will always be silent.
- Changed some admin buttons to use the new event system.
- Added a forceEvent proc which you can use when you enable debug verbs.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@5525 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
giacomand@gmail.com
2013-01-12 16:44:06 +00:00
parent 616fcf1e88
commit a56e922053
29 changed files with 8275 additions and 7512 deletions

View File

@@ -1924,10 +1924,8 @@
if("wave")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","MW")
meteor_wave()
message_admins("[key_name_admin(usr)] has spawned meteors", 1)
command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert")
world << sound('sound/AI/meteors.ogg')
new /datum/event/meteor_wave
if("gravanomalies")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","GA")
@@ -1954,7 +1952,7 @@
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","AL")
if(aliens_allowed)
alien_infestation()
new /datum/event/alien_infestation
message_admins("[key_name_admin(usr)] has spawned aliens", 1)
if("alien_silent") //replaces the spawn_xeno verb
feedback_inc("admin_secrets_fun_used",1)
@@ -1982,12 +1980,12 @@
var/choice = input("You sure you want to spawn carp?") in list("Badmin", "Cancel")
if(choice == "Badmin")
message_admins("[key_name_admin(usr)] has spawned carp.", 1)
carp_migration()
new /datum/event/carp_migration
if("radiation")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","R")
message_admins("[key_name_admin(usr)] has has irradiated the station", 1)
high_radiation_event()
new /datum/event/radiation_storm
if("immovable")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","IR")
@@ -2150,7 +2148,7 @@
if("spacevines")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","K")
spacevine_infestation()
new /datum/event/spacevine
message_admins("[key_name_admin(usr)] has spawned spacevines", 1)
if("onlyone")
feedback_inc("admin_secrets_fun_used",1)

View File

@@ -152,6 +152,7 @@ var/intercom_range_display_status = 0
src.verbs += /datum/admins/proc/show_traitor_panel
src.verbs += /client/proc/print_jobban_old
src.verbs += /client/proc/print_jobban_old_filter
src.verbs += /client/proc/forceEvent
//src.verbs += /client/proc/cmd_admin_rejuvenate
feedback_add_details("admin_verb","mDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -1,10 +1,14 @@
/datum/event/alien_infestation
announceWhen = 75
endWhen = 75
oneShot = 1
var/spawncount = 1
/datum/event/alien_infestation/setup()
announceWhen = rand(140, 180)
spawncount = rand(1, 2)
/datum/event/alien_infestation/announce()
command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
world << sound('sound/AI/aliens.ogg')
@@ -19,7 +23,6 @@
var/list/candidates = get_alien_candidates()
if(prob(50)) spawncount++ //sometimes, have two larvae spawn instead of one
while((spawncount >= 1) && vents.len && candidates.len)
var/obj/vent = pick(vents)
var/candidate = pick(candidates)

View File

@@ -16,9 +16,8 @@
kill()
return
Blob = new /obj/effect/blob/core(T, 200)
Blob.Life()
Blob.Life()
Blob.Life()
for(var/i = 1; i < rand(3, 6), i++)
Blob.process()
/datum/event/blob/tick()
@@ -26,4 +25,4 @@
kill()
return
if(IsMultiple(activeFor, 3))
Blob.Life()
Blob.process()

View File

@@ -1,8 +1,9 @@
/datum/event/carp_migration
announceWhen = 50
endWhen = 50
oneShot = 1
/datum/event/carp_migration/setup()
announceWhen = rand(40, 60)
/datum/event/carp_migration/announce()
command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")

View File

@@ -7,8 +7,8 @@
/datum/event/communications_blackout/start()
if(prob(25))
silent = 0
//if(prob(25))
// silent = 0
for(var/mob/living/silicon/ai/A in player_list) //AIs are always aware of communication blackouts.
A << "<br>"
A << "<span class='warning'><b>Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT<b></span>"

View File

@@ -1,6 +1,5 @@
/datum/event/disease_outbreak
announceWhen = 15
endWhen = 15
oneShot = 1
@@ -8,6 +7,9 @@
command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
world << sound('sound/AI/outbreak7.ogg')
/datum/event/disease_outbreak/setup()
announceWhen = rand(15, 30)
/datum/event/disease_outbreak/start()
var/virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis)

View File

@@ -1,13 +1,17 @@
/datum/event //NOTE: Times are measured in master controller ticks!
var/startWhen = 0 //When in the lifetime to call start().
var/announceWhen = 0 //When in the lifetime to call announce().
var/endWhen = 0 //When in the lifetime the event should end. Include time for delayed announcements.
var/endWhen = 0 //When in the lifetime the event should end.
var/oneShot = 0 //If true, then the event removes itself from the list of potential events on creation.
var/activeFor = 0 //How long the event has existed. You don't need to change this.
//Called first before processing.
//Allows you to setup your event, such as randomly
//setting the startWhen and or announceWhen variables.
//Only called once.
/datum/event/proc/setup()
return
//Called when the tick is equal to the startWhen variable.
//Allows you to start before announcing or vice versa.
@@ -39,21 +43,24 @@
//Do not override this proc, instead use the appropiate procs.
//This proc will handle the calls to the appropiate procs.
/datum/event/proc/process()
if(activeFor > startWhen && activeFor < endWhen)
tick()
if(activeFor == startWhen)
start()
if(activeFor > startWhen)
tick()
if(activeFor == announceWhen)
announce()
if(activeFor >= endWhen)
if(activeFor == endWhen)
end()
// Everything is done, let's clean up.
if(activeFor >= endWhen && activeFor >= announceWhen && activeFor >= startWhen)
kill()
activeFor++
@@ -61,6 +68,7 @@
//Garbage collects the event by removing it from the global events list,
//which should be the only place it's referenced.
//Called when start(), announce() and end() has all been called.
/datum/event/proc/kill()
events.Remove(src)
@@ -68,7 +76,8 @@
//Adds the event to the global events list, and removes it from the list
//of potential events.
/datum/event/New()
setup()
events.Add(src)
if(oneShot)
potentialRandomEvents.Remove(type)
potentialRandomEvents.Remove(type)
..()

View File

@@ -36,4 +36,15 @@ var/scheduledEvent = null
//The event will add itself to the MC's event list
//and start working via the constructor.
new Type
new Type
/client/proc/forceEvent(var/type in allEvents)
set name = "Trigger Event (Debug Only)"
set category = "Debug"
if(!holder)
return
if(ispath(type))
new type
message_admins("[key_name_admin(usr)] has triggered an event. ([type])", 1)

View File

@@ -1,12 +1,16 @@
/datum/event/prison_break
announceWhen = 50
endWhen = 50
oneShot = 1
var/releaseWhen = 25
var/list/area/prisonAreas = list()
/datum/event/prison_break/setup()
announceWhen = rand(50, 60)
releaseWhen = rand(20, 30)
/datum/event/prison_break/announce()
if(prisonAreas && prisonAreas.len > 0)
command_alert("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
@@ -26,6 +30,13 @@
L.flicker(10)
/datum/event/prison_break/announce()
if(prisonAreas && prisonAreas.len > 0)
command_alert("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
else
world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area."
/datum/event/prison_break/tick()
if(activeFor == releaseWhen)
if(prisonAreas && prisonAreas.len > 0)

View File

@@ -1,6 +1,5 @@
/datum/event/radiation_storm
announceWhen = 5
endWhen = 5
oneShot = 1

View File

@@ -1,5 +1,5 @@
/datum/event/spontaneous_appendicitis/start()
for(var/mob/living/carbon/human/H in living_mob_list)
for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
var/foundAlready = 0 //don't infect someone that already has the virus
for(var/datum/disease/D in H.viruses)
foundAlready = 1

View File

@@ -0,0 +1,175 @@
//goat
/mob/living/simple_animal/hostile/retaliate/goat
name = "goat"
desc = "Not known for their pleasant disposition."
icon_state = "goat"
icon_living = "goat"
icon_dead = "goat_dead"
speak = list("EHEHEHEHEH","eh?")
speak_emote = list("brays")
emote_hear = list("brays")
emote_see = list("shakes its head", "stamps a foot", "glares around")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 4
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
faction = "neutral"
attacktext = "kicks"
health = 40
melee_damage_lower = 1
melee_damage_upper = 5
/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
/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].")
var/obj/item/weapon/reagent_containers/glass/G = O
G.reagents.add_reagent("milk",rand(7,12))
if(G.reagents.total_volume >= G.volume)
user << "\red The [O] is full."
else
..()
//cow
/mob/living/simple_animal/cow
name = "cow"
desc = "Known for their milk, just don't tip them over."
icon_state = "cow"
icon_living = "cow"
icon_dead = "cow_dead"
icon_gib = "cow_gib"
speak = list("moo?","moo","MOOOOOO")
speak_emote = list("moos","moos hauntingly")
emote_hear = list("brays")
emote_see = list("shakes its head")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 6
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
attacktext = "kicks"
health = 50
/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].")
var/obj/item/weapon/reagent_containers/glass/G = O
G.reagents.add_reagent("milk",rand(5,10))
if(G.reagents.total_volume >= G.volume)
user << "\red The [O] is full."
else
..()
/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M as mob)
if(!stat && M.a_intent == "help")
M.visible_message("\red [M] tips over [src].","\red You tip over [src].")
src.Weaken(30)
icon_state = "cow_dead"
spawn(rand(20,50))
if(!stat)
icon_state = "cow"
var/list/responses = list( "\red [src] looks at you imploringly.",
"\red [src] looks at you pleadingly",
"\red [src] looks at you with a resigned expression.",
"\red [src] seems resigned to it's fate.")
M << pick(responses)
else
..()
/mob/living/simple_animal/chick
name = "chick"
desc = "Adorable! They make such a racket though"
icon_state = "chick"
icon_living = "chick"
icon_dead = "chick_dead"
icon_gib = "chick_gib"
speak = list("cherp","cherp?","chirrup","cheep")
speak_emote = list("cheeps")
emote_hear = list("cheeps")
emote_see = list("pecks at the ground","flaps it's tiny wings")
speak_chance = 10
turns_per_move = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 1
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
attacktext = "kicks"
health = 1
var/amount_grown = 0
pass_flags = PASSTABLE | PASSGRILLE
New()
..()
pixel_x = rand(-6,6)
pixel_y = rand(-6,6)
/mob/living/simple_animal/chick/Life()
..()
if(!stat)
amount_grown += rand(1,2)
if(amount_grown >= 100)
new /mob/living/simple_animal/chicken(src.loc)
del(src)
/mob/living/simple_animal/chicken
name = "chicken"
desc = "Hopefully the eggs are good this season."
icon_state = "chicken"
icon_living = "chicken"
icon_dead = "chicken_dead"
speak = list("cluck","BWAAAAARK BWAK BWAK BWAK","bwaak bwak")
speak_emote = list("clucks","croons")
emote_hear = list("clucks")
emote_see = list("pecks at the ground","flaps it's wings viciously")
speak_chance = 10
turns_per_move = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 2
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
attacktext = "kicks"
health = 10
pass_flags = PASSTABLE
New()
..()
pixel_x = rand(-6,6)
pixel_y = rand(-6,6)
/mob/living/simple_animal/chicken/Life()
..()
if(!stat && prob(1))
src.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)
E.pixel_x = rand(-6,6)
E.pixel_y = rand(-6,6)
processing_objects.Add(E)
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))
src.visible_message("[src] hatches with a quiet cracking sound.")
new /mob/living/simple_animal/chick(src.loc)
processing_objects.Remove(src)
del(src)

View File

@@ -0,0 +1,220 @@
#define SPINNING_WEB 1
#define LAYING_EGGS 2
#define MOVING_TO_TARGET 3
#define SPINNING_COCOON 4
//basic spider mob, these generally guard nests
/mob/living/simple_animal/hostile/giant_spider
name = "giant spider"
desc = "Furry and black, it makes you shudder to look at it. This one has deep red eyes."
icon_state = "guard"
icon_living = "guard"
icon_dead = "guard_dead"
speak_emote = list("chitters")
emote_hear = list("chitters")
speak_chance = 5
turns_per_move = 5
see_in_dark = 10
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "pokes the"
stop_automated_movement_when_pulled = 0
maxHealth = 200
health = 200
melee_damage_lower = 15
melee_damage_upper = 20
var/poison_per_bite = 5
var/poison_type = "mindbreaker"
faction = "spiders"
var/busy = 0
pass_flags = PASSTABLE
//nursemaids - these create webs and eggs
/mob/living/simple_animal/hostile/giant_spider/nurse
desc = "Furry and black, it makes you shudder to look at it. This one has brilliant green eyes."
icon_state = "nurse"
icon_living = "nurse"
icon_dead = "nurse_dead"
maxHealth = 40
health = 40
melee_damage_lower = 5
melee_damage_upper = 10
poison_per_bite = 10
var/atom/cocoon_target
poison_type = "zombiepowder"
var/fed = 0
//hunters have the most poison and move the fastest, so they can find prey
/mob/living/simple_animal/hostile/giant_spider/hunter
desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes."
icon_state = "hunter"
icon_living = "hunter"
icon_dead = "hunter_dead"
maxHealth = 120
health = 120
melee_damage_lower = 10
melee_damage_upper = 20
poison_per_bite = 20
/mob/living/simple_animal/hostile/giant_spider/AttackingTarget()
..()
if(isliving(target_mob))
var/mob/living/L = target_mob
if(L.reagents)
L.reagents.add_reagent("toxin", poison_per_bite)
if(prob(poison_per_bite))
L << "\red You feel a tiny prick."
L.reagents.add_reagent(poison_type, 5)
/mob/living/simple_animal/hostile/giant_spider/Life()
..()
if(!stat)
if(stance == HOSTILE_STANCE_IDLE)
//10% chance to skitter madly away
if(!busy && prob(10))
/*var/list/move_targets = list()
for(var/turf/T in orange(20, src))
move_targets.Add(T)*/
stop_automated_movement = 1
walk_to(src, pick(orange(20, src)), 1, move_to_delay)
spawn(50)
stop_automated_movement = 0
walk(src,0)
/mob/living/simple_animal/hostile/giant_spider/nurse/proc/GiveUp(var/C)
spawn(100)
if(busy == MOVING_TO_TARGET)
if(cocoon_target == C && get_dist(src,cocoon_target) > 1)
cocoon_target = null
busy = 0
stop_automated_movement = 0
/mob/living/simple_animal/hostile/giant_spider/nurse/Life()
..()
if(!stat)
if(stance == HOSTILE_STANCE_IDLE)
var/list/can_see = ListTargets()
//30% chance to stop wandering and do something
if(!busy && prob(30))
//first, check for potential food nearby to cocoon
for(var/mob/living/C in can_see)
if(C.stat)
cocoon_target = C
busy = MOVING_TO_TARGET
walk_to(src, C, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(C)
return
//second, spin a sticky spiderweb on this tile
var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
if(!W)
busy = SPINNING_WEB
src.visible_message("\blue \the [src] begins to secrete a sticky substance.")
stop_automated_movement = 1
spawn(40)
if(busy == SPINNING_WEB)
new /obj/effect/spider/stickyweb(src.loc)
busy = 0
stop_automated_movement = 0
else
//third, lay an egg cluster there
var/obj/effect/spider/eggcluster/E = locate() in get_turf(src)
if(!E && fed > 0)
busy = LAYING_EGGS
src.visible_message("\blue \the [src] begins to lay a cluster of eggs.")
stop_automated_movement = 1
spawn(50)
if(busy == LAYING_EGGS)
E = locate() in get_turf(src)
if(!E)
new /obj/effect/spider/eggcluster(src.loc)
fed--
busy = 0
stop_automated_movement = 0
else
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
for(var/obj/O in can_see)
if(istype(O, /obj/item))
var/obj/item/I = O
cocoon_target = I
busy = MOVING_TO_TARGET
stop_automated_movement = 1
walk_to(src, I, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(I)
return
if(istype(O, /obj/structure))
var/obj/structure/S = O
if(S.anchored)
continue
cocoon_target = S
busy = MOVING_TO_TARGET
stop_automated_movement = 1
walk_to(src, S, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(S)
return
if(istype(O, /obj/machinery))
var/obj/machinery/M = O
if(M.anchored)
continue
cocoon_target = M
busy = MOVING_TO_TARGET
stop_automated_movement = 1
walk_to(src, M, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(M)
return
else if(busy == MOVING_TO_TARGET && cocoon_target)
if(get_dist(src, cocoon_target) <= 1)
busy = SPINNING_COCOON
src.visible_message("\blue \the [src] begins to secrete a sticky substance around \the [cocoon_target].")
stop_automated_movement = 1
walk(src,0)
spawn(50)
if(busy == SPINNING_COCOON)
if(cocoon_target && istype(cocoon_target.loc, /turf) && get_dist(src,cocoon_target) <= 1)
var/obj/effect/spider/cocoon/C = new(cocoon_target.loc)
var/large_cocoon = 0
C.pixel_x = cocoon_target.pixel_x
C.pixel_y = cocoon_target.pixel_y
for(var/mob/living/M in C.loc)
if(istype(M, /mob/living/simple_animal/hostile/giant_spider))
continue
large_cocoon = 1
fed++
src.visible_message("\red \the [src] sticks a proboscis into \the [cocoon_target] and sucks a viscous substance out.")
M.loc = C
C.pixel_x = M.pixel_x
C.pixel_y = M.pixel_y
break
for(var/obj/item/I in C.loc)
I.loc = C
for(var/obj/structure/S in C.loc)
if(!S.anchored)
S.loc = C
large_cocoon = 1
for(var/obj/machinery/M in C.loc)
if(!M.anchored)
M.loc = C
large_cocoon = 1
if(large_cocoon)
C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
busy = 0
stop_automated_movement = 0
else
busy = 0
stop_automated_movement = 0
#undef SPINNING_WEB
#undef LAYING_EGGS
#undef MOVING_TO_TARGET
#undef SPINNING_COCOON

View File

@@ -18,6 +18,10 @@
stop_automated_movement = 0
for(var/atom/A in ListTargets())
T = Found(A)
if(T)
break
if(isliving(A))
var/mob/living/L = A
if(L.faction == src.faction && !attack_same)
@@ -29,6 +33,7 @@
stance = HOSTILE_STANCE_ATTACK
T = L
break
if(istype(A, /obj/mecha))
var/obj/mecha/M = A
if (M.occupant)
@@ -37,6 +42,10 @@
break
return T
/mob/living/simple_animal/hostile/proc/Found(var/atom/A)
return
/mob/living/simple_animal/hostile/proc/MoveToTarget()
stop_automated_movement = 1
if(!target_mob || SA_attackable(target_mob))
@@ -163,4 +172,4 @@
for(var/dir in cardinal) // North, South, East, West
var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
obstacle.attack_animal(src)
obstacle.attack_animal(src)

View File

@@ -0,0 +1,39 @@
/mob/living/simple_animal/hostile/retaliate/clown
name = "Clown"
desc = "A denizen of clown planet"
icon_state = "clown"
icon_living = "clown"
icon_dead = "clown_dead"
icon_gib = "clown_gib"
speak_chance = 0
turns_per_move = 5
response_help = "pokes the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
speak = list("HONK", "Honk!", "Welcome to clown planet!")
emote_see = list("honks")
speak_chance = 1
a_intent = "harm"
stop_automated_movement_when_pulled = 0
maxHealth = 75
health = 75
speed = -1
harm_intent_damage = 8
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "attacks"
attack_sound = 'sound/items/bikehorn.ogg'
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
minbodytemp = 270
maxbodytemp = 370
heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
unsuitable_atoms_damage = 10

View File

@@ -0,0 +1,30 @@
/mob/living/simple_animal/hostile/retaliate
var/list/enemies = list()
/mob/living/simple_animal/hostile/retaliate/Found(var/atom/A)
if(isliving(A))
var/mob/living/L = A
if(L in enemies)
if(!L.stat)
stance = HOSTILE_STANCE_ATTACK
return L
else
enemies -= L
/mob/living/simple_animal/hostile/retaliate/proc/retaliate()
..()
var/list/mobs_around = viewers(src, 7)
for(var/mob/living/M in mobs_around)
if(!attack_same && istype(M, type))
enemies += M
for(var/mob/living/simple_animal/hostile/retaliate/H in mobs_around)
if(istype(H, src.type))
H.enemies += enemies
return 0
/mob/living/simple_animal/hostile/retaliate/adjustBruteLoss(var/damage)
..(damage)
retaliate()

View File

@@ -81,7 +81,7 @@
return 0
/proc/isclown(A)
if(istype(A, /mob/living/simple_animal/clown))
if(istype(A, /mob/living/simple_animal/hostile/retaliate/clown))
return 1
return 0

View File

@@ -979,7 +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/clown
/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

View File

@@ -26,7 +26,9 @@
/obj/machinery/bot/medbot,
/obj/machinery/computer/pandemic,
/obj/item/weapon/storage/secure/safe,
/obj/machinery/disposal
/obj/machinery/disposal,
/mob/living/simple_animal/cow,
/mob/living/simple_animal/hostile/retaliate/goat
)
examine()