Unfucks zombies (#13101)

* Unfucks zombies

* MAGIC FUCKING NUMBERS

* MAGIC_FUCKING_NUMBERS

* Apparently we don't use that file

* Good spots by comic
This commit is contained in:
Skullyton
2016-12-31 17:43:40 +00:00
committed by Probe1
parent a2f42672e3
commit bdedebe021
4 changed files with 148 additions and 78 deletions

View File

@@ -66,3 +66,9 @@
#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" //Weird color, between yellow and green, very slimy. rgb(175, 200, 75)
#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175)
#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250)
//Defines for lighting status, see power/lighting.dm
#define LIGHT_OK 0
#define LIGHT_EMPTY 1
#define LIGHT_BROKEN 2
#define LIGHT_BURNED 3

View File

@@ -101,7 +101,7 @@ var/global/list/spider_types = typesof(/mob/living/simple_animal/hostile/giant_s
if(istype(the_target,/obj/machinery/light))
var/obj/machinery/light/L = the_target
// Not empty or broken
return L.status != 1 && L.status != 2
return L.status != LIGHT_EMPTY && L.status != LIGHT_BROKEN
return ..(the_target)
/mob/living/simple_animal/hostile/giant_spider/proc/CanOpenDoor(var/obj/machinery/door/D)

View File

@@ -1,6 +1,33 @@
/mob/living/simple_animal/hostile/necro
var/mob/creator
var/unique_name = 0
faction = "necro"
/mob/living/simple_animal/hostile/necro/New(loc, mob/living/Owner, datum/mind/Controller)
..()
if(Owner)
faction = "\ref[Owner]"
friends.Add(Owner)
creator = Owner
if(Controller)
mind = Controller
ckey = ckey(mind.key)
to_chat(src, "<big><span class='warning'>You have been risen from the dead by your new master, [Owner]. Do his bidding so long as he lives, for when he falls so do you.</span></big>")
var/ref = "\ref[Owner.mind]"
var/list/necromancers
if(!(Owner.mind in ticker.mode.necromancer))
ticker.mode:necromancer[ref] = list()
necromancers = ticker.mode:necromancer[ref]
necromancers.Add(Controller)
ticker.mode:necromancer[ref] = necromancers
ticker.mode.update_necro_icons_added(Owner.mind)
ticker.mode.update_necro_icons_added(Controller)
ticker.mode.update_all_necro_icons()
ticker.mode.risen.Add(Controller)
if(name == initial(name) && !unique_name)
name += " ([rand(1,1000)])"
/mob/living/simple_animal/hostile/necro/skeleton
name = "skeleton"
desc = "Truly the ride never ends."
@@ -39,12 +66,14 @@
environment_smash = 1
meat_type = null
/*
#define EVOLVING 1
#define MOVING_TO_TARGET 2
#define EATING 3
#define OPENING_DOOR 4
//#define SMASHING_LIGHT 5
#define SMASHING_LIGHT 5*/
#define MAX_EAT_MULTIPLIER 4 //Dead for humans is -maxHealth, uncloneable is -maxHealth * 2
/mob/living/simple_animal/hostile/necro/zombie //Boring ol default zombie
name = "zombie"
@@ -73,6 +102,7 @@
melee_damage_upper = 20
attacktext = "bites"
attack_sound = 'sound/weapons/bite.ogg'
stat_attack = DEAD
min_oxy = 0
max_oxy = 0
@@ -89,7 +119,7 @@
var/times_revived //Tracks how many times the zombie has regenerated from death
var/times_eaten //Tracks how many times the zombie has chewed on a human corpse
var/can_evolve = FALSE //False if we don't want it to evolve
var/busy //If the zombie is busy, and what it's busy doing
//var/busy //If the zombie is busy, and what it's busy doing
#define CANT 0
#define CAN 1
@@ -99,44 +129,67 @@
var/break_doors = CANT //If CAN, they can attempt to open doors. If CANPLUS, they break the door down entirely
var/health_cap = 250 //Maximum possible health it can have. Because screw having a 1000 health mob
/* wanted_objects = list(
/obj/machinery/light, // Bust out lights
var/busy = FALSE //Stop spamming the damn doorsmash
wanted_objects = list(
/obj/machinery/light,
/obj/machinery/door // Bust out lights
)
search_objects = 1
/mob/living/simple_animal/hostile/necro/zombie/CanAttack(var/atom/the_target)
if(the_target == creator)
return 0
if(ismob(the_target))
var/mob/living/M = the_target
if(ishuman(the_target)) //Checking for food
var/mob/living/carbon/human/H = the_target
if(H.isDead())
if(check_edibility(H))
return the_target
else
return 0
else
return ..(the_target)
else
if(M.isDead())
return 0
if(istype(the_target,/obj/machinery/door)) //Checking for doors
var/obj/machinery/door/D = the_target
if(can_open_door(D))
return the_target
else
return 0
if(istype(the_target,/obj/machinery/light))
var/obj/machinery/light/L = the_target
// Not empty or broken
return L.status != 1 && L.status != 2
return ..(the_target)*/ //Too buggy, gets caught on terrain way too much
return L.status != LIGHT_EMPTY && L.status != LIGHT_BROKEN
return ..(the_target)
/mob/living/simple_animal/hostile/necro/zombie/AttackingTarget()
if(!target)
return
if(target == creator)
return
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.isDead() && check_edibility(H))
eat(H)
return 0
if(istype (target, /obj/machinery/door))
var/obj/machinery/door/D = target
if(can_open_door(D))
force_door(D)
return 0
return..()
/mob/living/simple_animal/hostile/necro/New(loc, mob/living/Owner, datum/mind/Controller)
..()
if(Owner)
faction = "\ref[Owner]"
friends.Add(Owner)
if(Controller)
mind = Controller
ckey = ckey(mind.key)
to_chat(src, "<big><span class='warning'>You have been risen from the dead by your new master, [Owner]. Do his bidding so long as he lives, for when he falls so do you.</span></big>")
var/ref = "\ref[Owner.mind]"
var/list/necromancers
if(!(Owner.mind in ticker.mode.necromancer))
ticker.mode:necromancer[ref] = list()
necromancers = ticker.mode:necromancer[ref]
necromancers.Add(Controller)
ticker.mode:necromancer[ref] = necromancers
ticker.mode.update_necro_icons_added(Owner.mind)
ticker.mode.update_necro_icons_added(Controller)
ticker.mode.update_all_necro_icons()
ticker.mode.risen.Add(Controller)
if(name == initial(name) && !unique_name)
name += " ([rand(1,1000)])"
/mob/living/simple_animal/hostile/necro/zombie/Life()
..()
/*TODONE
First, check if the zombie can potentially evolve
Have the zombie move to a corpse and start chewing at it
@@ -145,12 +198,10 @@
*/
if(!isUnconscious())
if(stance == HOSTILE_STANCE_IDLE && !client) //Not doing anything at the time
var/list/can_see = view(src, vision_range)
if(!busy)
if(can_evolve)//Can we evolve, and have we fed
busy = EVOLVING
check_evolve()
busy = 0
if(can_evolve)//Can we evolve, and have we fed
check_evolve()
..()
/*
if((health < maxHealth) || (maxHealth < health_cap) && !busy)
var/mob/living/carbon/human/C = find_food(can_see)//Is there something to eat in range?
if(C) //If so, chow down
@@ -162,6 +213,7 @@
eat(C)
C = null
walk(src, 0)
if(!busy && break_doors != CANT)//So we don't try to eat and open doors
var/obj/machinery/door/D = find_door(can_see)//Is there a door to open in range?
if(D)
@@ -173,13 +225,13 @@
force_door(D)
D = null
walk(src, 0)
else
busy = 0
stop_automated_movement = 0
else
walk(src,0)
*/
/*
/mob/living/simple_animal/hostile/necro/zombie/proc/find_food(var/list/can_see)
for(var/mob/living/carbon/human/C in can_see) //Because of how can_see lists things, it'll go in order of closest to furthest
if(C.isDead() && check_edibility(C))
@@ -198,7 +250,10 @@
busy = 0
stop_automated_movement = 0
walk(src,0)
*/
/mob/living/simple_animal/hostile/necro/zombie/proc/can_open_door(var/obj/machinery/door/D)
if(busy) //Already smashing a door or eating something
return 0
if((istype(D,/obj/machinery/door/poddoor) || istype(D, /obj/machinery/door/airlock/multi_tile/glass) || istype(D, /obj/machinery/door/window)) && !client)
return 0
if(break_doors == CANT)//Moreso used for when a player-controlled zombie attempts to forceopen a door
@@ -236,47 +291,57 @@
D.visible_message("<span class='warning'>\The [D]'s motors whine as something attempts to brute force their way through it!</span>")
playsound(get_turf(D), 'sound/effects/grillehit.ogg', 50, 1)
D.shake(1, 8)
if(do_after(src, D, 100*time_mult, needhand = FALSE)) //Roughly 10 seconds for people on the other side of the door to run the heck away
if(can_open_door(D))//Let's see if nobody quickly bolted it
if(break_doors == CANPLUS) //Guaranteed
D.visible_message("<span class='warning'>\The [D] breaks open under the pressure</span>")
if(istype(D, /obj/machinery/door/airlock/))
var/obj/machinery/door/airlock/A = D
A.locked = 0
A.welded = 0
A.jammed = 0
D.open(1)
else
if(prob(33))
D.visible_message("<span class='warning'>\The [D] creaks open under force, steadily</span>")
busy = TRUE
var/target_loc = D.loc
var/self_loc = src.loc
spawn(10 SECONDS*time_mult)
if(D.loc == target_loc && self_loc == src.loc) //Not moved
if(can_open_door(D))//Let's see if nobody quickly bolted it
if(break_doors == CANPLUS) //Guaranteed
D.visible_message("<span class='warning'>\The [D] breaks open under the pressure</span>")
if(istype(D, /obj/machinery/door/airlock/))
var/obj/machinery/door/airlock/A = D
A.locked = 0
A.welded = 0
A.jammed = 0
D.open(1)
busy = 0
else
if(prob(33))
D.visible_message("<span class='warning'>\The [D] creaks open under force, steadily</span>")
D.open(1)
else
playsound(get_turf(D), 'sound/effects/grillehit.ogg', 50, 1)
D.shake(1, 8)
busy = FALSE
stop_automated_movement = 0
/mob/living/simple_animal/hostile/necro/zombie/proc/check_edibility(var/mob/living/carbon/human/target)
if(!(target.isDead()))
return 0 //It ain't dead
if(isjusthuman(target)) //Humans are always edible
return 1
if(target.health > -400) //So they're not caught eating the same dumb bird all day
return 1
if(busy)
return 0
if((health < maxHealth) || (maxHealth < health_cap))
if(!(target.isDead()))
return 0 //It ain't dead
if(isjusthuman(target)) //Humans are always edible
return 1
if(target.health > -(target.maxHealth*MAX_EAT_MULTIPLIER)) //So they're not caught eating the same dumb bird all day
return 1
return 0
/mob/living/simple_animal/hostile/necro/zombie/proc/eat(var/mob/living/carbon/human/target)
//Deal a random amount of brute damage to the corpse in question, heal the zombie by the damage dealt halved
visible_message("<span class='notice'>\The [src] starts to take a bite out of \the [target].</span>")
visible_message("<span class='warning'>\The [src] takes a bite out of \the [target].</span>")
busy = TRUE
stop_automated_movement = 1
if(do_after(src, target, 50, needhand = FALSE))
playsound(get_turf(src), 'sound/weapons/bite.ogg', 50, 1)
var/damage = rand(melee_damage_lower, melee_damage_upper)
target.adjustBruteLoss(damage)
health = min(maxHealth, health+damage)
if(maxHealth < health_cap)
maxHealth += 5 //A well fed zombie is a scary zombie
times_eaten += 1
playsound(get_turf(src), 'sound/weapons/bite.ogg', 50, 1)
var/damage = rand(melee_damage_lower, melee_damage_upper)
target.adjustBruteLoss(damage)
if(maxHealth < health_cap)
maxHealth += 5 //A well fed zombie is a scary zombie
health = min(maxHealth, health+damage)
times_eaten += 1
busy = FALSE
stop_automated_movement = 0
busy = 0
/mob/living/simple_animal/hostile/necro/zombie/proc/check_evolve()
if(!can_evolve) //How did you get here if not?
@@ -311,8 +376,11 @@
/mob/living/simple_animal/hostile/necro/zombie/proc/evolve(var/mob/living/simple_animal/evolve_to)
if(ispath(evolve_to, /mob/living/simple_animal/hostile/necro))
var/mob/living/evolution = new evolve_to(src.loc,,)
var/mob/living/simple_animal/hostile/necro/evolution = new evolve_to(src.loc,,)
evolution.name = name //We want to keep the name
evolution.inherit_mind(src)
evolution.creator = creator
evolution.friends = friends.Copy()
if(mind)
mind.transfer_to(evolution) //Just in the offchance we have a player in control
qdel(src)
@@ -326,6 +394,9 @@
times_revived += 1
/mob/living/simple_animal/hostile/necro/zombie/UnarmedAttack(atom/A) //There's got to be a better way to keep everything together
if(A == creator) //Evil necromancy magic means no attacking our creator
to_chat(src, "Try as you might, you can't bring yourself to attack [A]")
return
..()
if(istype(A, /obj/machinery/door))
if(can_open_door(A))

View File

@@ -2,13 +2,6 @@
//
// consists of light fixtures (/obj/machinery/light) and light tube/bulb items (/obj/item/weapon/light)
// status values shared between lighting fixtures and items
#define LIGHT_OK 0
#define LIGHT_EMPTY 1
#define LIGHT_BROKEN 2
#define LIGHT_BURNED 3
/obj/machinery/light_construct
name = "light fixture frame"
desc = "A light fixture under construction."