Facehugger overhaul

They now function like landmines. They don't move, but you can pick them up and throw them at people.
Eggs now grow gradually and you can harvest a hugger from a grown egg.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@2438 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
uporotiy
2011-10-28 17:17:01 +00:00
parent 9bb5f06ea0
commit c0d8adf42f
21 changed files with 918 additions and 679 deletions
+2 -2
View File
@@ -64,10 +64,10 @@
if(G.client)
if(G.client.be_alien)
if(((G.client.inactivity/10)/60) <= 5)
if(G.corpse) //hopefully will make adminaliums possible --Urist
if(G.corpse)
if(G.corpse.stat==2)
candidates.Add(G)
if(!G.corpse) //hopefully will make adminaliums possible --Urist
if(!G.corpse)
candidates.Add(G)
if(candidates.len)
var/mob/dead/observer/G = pick(candidates)
+1 -1
View File
@@ -233,7 +233,7 @@
name = "welding helmet"
desc = "A head-mounted face cover designed to protect the wearer completely from space-arc eye."
icon_state = "welding"
flags = FPRINT | TABLEPASS | SUITSPACE | HEADCOVERSEYES
flags = FPRINT | TABLEPASS | SUITSPACE | HEADCOVERSEYES | HEADCOVERSMOUTH
see_face = 0.0
item_state = "welding"
protective_temperature = 1300
+1 -1
View File
@@ -145,7 +145,7 @@ proc/admin_spawn_room_at_pos()
spawn_room(locate(x,y,z),x_len,y_len,wall,floor)
return
var/global/list/space_surprises = list(/obj/effect/alien/facehugger,
var/global/list/space_surprises = list(/obj/item/clothing/mask/facehugger,
/obj/effect/critter/spesscarp,
/obj/effect/critter/spesscarp/elite,
// /obj/creature,
+1 -1
View File
@@ -25,7 +25,7 @@
/turf/simulated/wall/asteroid/facehugger
icon_state = "asteroid_i"
contains = /obj/effect/alien/facehugger
contains = /obj/item/clothing/mask/facehugger
max_amount = 1
min_amount = 0
+24 -8
View File
@@ -281,17 +281,33 @@
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
if(temp_vent.loc.z == 1 && !temp_vent.welded)
vents.Add(temp_vent)
var/spawncount = rand(2, 6)
while(spawncount > 1)
var/spawncount = 1
if(prob(10)) spawncount++ //rarely, have two larvae spawn instead of one
while(spawncount >= 1)
var/obj/vent = pick(vents)
if(prob(50))
new /obj/effect/alien/facehugger (vent.loc)
if(prob(50))
new /obj/effect/alien/facehugger (vent.loc)
if(prob(75))
new /obj/effect/alien/egg (vent.loc)
var/list/candidates = list() // Picks a random ghost in the world to shove in the larva -- TLE; If there's no ghost... well, sucks. Wasted event. -- Urist
for(var/mob/dead/observer/G in world)
if(G.client)
if(G.client.be_alien)
if(((G.client.inactivity/10)/60) <= 5)
if(G.corpse)
if(G.corpse.stat==2)
candidates.Add(G)
if(!G.corpse)
candidates.Add(G)
if(candidates.len)
var/mob/dead/observer/G = pick(candidates)
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
new_xeno.mind_initialize(G,"Larva")
new_xeno.key = G.key
del(G)
vents.Remove(vent)
spawncount -= 1
spawn(rand(3000, 6000)) //Delayed announcements to keep the crew on their toes.
command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
world << sound('aliens.ogg')
+8 -8
View File
@@ -16,10 +16,10 @@
if(src.check_access_list(critter.access_list))
if(density)
open()
else if(istype(AM, /obj/effect/alien/facehugger))
if(src.check_access(null))
if(density)
open()
// else if(istype(AM, /obj/effect/alien/facehugger))
// if(src.check_access(null))
// if(density)
// open()
else if(istype(AM, /obj/mecha))
var/obj/mecha/mecha = AM
if(density)
@@ -327,10 +327,10 @@
if(src.check_access(bot.botcard))
if(density)
open()
else if(istype(AM, /obj/effect/alien/facehugger))
if(src.check_access(null))
if(density)
open()
// else if(istype(AM, /obj/effect/alien/facehugger))
// if(src.check_access(null))
// if(density)
// open()
/obj/machinery/door/unpowered
autoclose = 0
+1 -11
View File
@@ -2,17 +2,7 @@
name = "alien thing"
desc = "theres something alien about this"
icon = 'alien.dmi'
unacidable = 1 //Aliens won't ment their own.
/obj/effect/alien/egg
desc = "It looks like a weird egg"
name = "egg"
icon_state = "egg"
density = 0
anchored = 0
var/health = 100
// unacidable = 1 //Aliens won't ment their own.
/obj/effect/alien/head
name = "severed head"
+68 -17
View File
@@ -1,16 +1,69 @@
/obj/effect/alien/egg/New()
if(aliens_allowed)
src.density = 0 // Aliens use resin walls to block paths now. I am lazy and didn't feel like going to the define. -- TLE
spawn(1800)
src.open()
else
del(src)
/var/const //for the status var
BURST = 0
GROWING = 1
GROWN = 2
/obj/effect/alien/egg/proc/open()
spawn(10)
src.density = 0
src.icon_state = "egg_hatched"
new /obj/effect/alien/facehugger(src.loc)
MIN_GROWTH_TIME = 1800 //time it takes to grow a hugger
MAX_GROWTH_TIME = 3000
/obj/effect/alien/egg
desc = "It looks like a weird egg"
name = "egg"
icon_state = "egg_growing"
density = 0
anchored = 1
var/health = 100
var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive
New()
if(aliens_allowed)
..()
spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
Grow()
else
del(src)
attack_paw(user as mob)
if(isalien(user))
switch(status)
if(BURST)
user << "\red The child is already gone."
return
if(GROWING)
user << "\red The child is not developed yet."
return
if(GROWN)
user << "\red You retrieve the child."
loc.contents += GetFacehugger()//need to write the code for giving it to the alien later
Burst()
return
else
return attack_hand(user)
attack_hand(user as mob)
user << "It feels slimy."
return
proc/GetFacehugger()
return locate(/obj/item/clothing/mask/facehugger) in contents
proc/Grow()
icon_state = "egg"
status = GROWN
new /obj/item/clothing/mask/facehugger(src)
return
proc/Burst() //drops and kills the hugger if any is remaining
var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
if(child)
loc.contents += child
child.Die()
icon_state = "egg_hatched"
status = BURST
return
/obj/effect/alien/egg/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
@@ -18,6 +71,8 @@
healthcheck()
return
/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user)
if(health <= 0)
return
@@ -37,11 +92,7 @@
/obj/effect/alien/egg/proc/healthcheck()
if(health <= 0)
if(prob(15))
open()
else
src.icon_state = "egg_hatched"
Burst()
/obj/effect/alien/egg/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 500)
+191 -2
View File
@@ -1,8 +1,196 @@
#define cycle_pause 5 //min 1
#define viewrange 7 //min 2
var/const
MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
MAX_IMPREGNATION_TIME = 150
MIN_ACTIVE_TIME = 30 //time between being dropped and going idle
MAX_ACTIVE_TIME = 50
/obj/item/clothing/mask/facehugger
name = "alien"
desc = "It has some sort of a tube at the end of its tail."
icon_state = "facehugger"
item_state = "facehugger"
w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
flags = FPRINT|TABLEPASS|MASKCOVERSMOUTH|MASKCOVERSEYES
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
var/sterile = 0
var/strength = 5
attack_paw(user as mob) //can be picked up by aliens
if(isalien(user))
attack_hand(user)
return
else
..()
return
attack_hand(user as mob)
if(stat == CONSCIOUS && !isalien(user))
Attach(user)
return
else
..()
return
attack(mob/living/M as mob, mob/user as mob)
..()
Attach(M)
New()
if(aliens_allowed)
..()
else
del(src)
examine()
..()
switch(stat)
if(DEAD,UNCONSCIOUS)
usr << "\red \b [src] is not moving."
if(CONSCIOUS)
usr << "\red \b [src] seems to be active."
if (sterile)
usr << "\red \b It looks like the proboscis has been removed."
return
attackby()
Die()
return
bullet_act()
Die()
return
HasEntered(atom/target)
Attach(target)
return
dropped()
..()
GoActive()
return
throw_impact(atom/hit_atom)
Attach(hit_atom)
return
proc/Attach(M as mob)
if(!isliving(M) || isalien(M))
return
var/mob/living/L = M //just so I don't need to use :
if(stat != CONSCIOUS)
return
L.take_organ_damage(strength,0) //done here so that even borgs and humans take damage
if(issilicon(L))
for(var/mob/O in viewers(src, null))
O.show_message("\red \b [src] smashes against [L]'s frame!", 1)
Die()
return
var/mob/living/carbon/target = L
for(var/mob/O in viewers(target, null))
O.show_message("\red \b [src] leaps at [target]'s face!", 1)
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.head && H.head.flags & HEADCOVERSMOUTH)
for(var/mob/O in viewers(H, null))
O.show_message("\red \b [src] smashes against [H]'s [H.head]!", 1)
Die()
return
if(target.wear_mask)
var/obj/item/clothing/W = target.wear_mask
if(W.canremove)
target.u_equip(W)
if (target.client)
target.client.screen -= W
W.loc = target.loc
W.dropped(target)
W.layer = initial(W.layer)
for(var/mob/O in viewers(target, null))
O.show_message("\red \b [src] tears [W] off of [target]'s face!", 1)
if(istype(loc,/mob/living/carbon/alien)) //just taking it off from the alien's UI
var/mob/living/carbon/alien/host = loc
host.u_equip(src)
if (host.client)
host.client.screen -= src
add_fingerprint(host)
loc = target
layer = 20
target.wear_mask = src
target.update_clothing()
GoIdle() //so it doesn't jump the people that tear it off
target.paralysis = max(target.paralysis,MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
Impregnate(target)
return
proc/Impregnate(mob/living/carbon/target as mob)
if(target.wear_mask != src) //was taken off or something
return
target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
for(var/datum/disease/alien_embryo/A in target.viruses)
target.alien_egg_flag = max(1,target.alien_egg_flag)
for(var/mob/O in viewers(target,null))
O.show_message("\red \b [src] falls limp after violating [target]'s face!", 1)
Die()
return
proc/GoActive()
if(stat == DEAD || stat == CONSCIOUS)
return
stat = CONSCIOUS
spawn(rand(MIN_ACTIVE_TIME,MAX_ACTIVE_TIME))
GoIdle()
return
proc/GoIdle()
if(stat == DEAD || stat == UNCONSCIOUS)
return
stat = UNCONSCIOUS
return
proc/Die()
if(stat == DEAD)
return
icon_state = "facehugger_dead"
stat = DEAD
for(var/mob/O in viewers(src, null))
O.show_message("\red \b[src] curls up into a ball!", 1)
return
/* NOPE.png -- Urist
// Returns the surrounding cardinal turfs with open links
// Including through doors openable with the ID
@@ -400,3 +588,4 @@
if (health <= 0)
death()
*/
+3 -1
View File
@@ -140,7 +140,9 @@
/obj/item/attack_paw(mob/user as mob)
if(isalien(user)) // -- TLE
if(!user:has_fine_manipulation) // -- defaults to 0, only changes due to badminnery -- Urist
var/mob/living/carbon/alien/A = user
if(!A.has_fine_manipulation || w_class >= 4)
user << "Your claws aren't capable of such fine manipulation."
return
+14 -19
View File
@@ -14,11 +14,7 @@
switch(severity)
if (1)
new /obj/item/weapon/shard( src.loc )
if (occupied)
var/obj/effect/alien/facehugger/A = new /obj/effect/alien/facehugger( src.loc )
A.lamarr = 1
A.name = "Lamarr"
occupied = 0
Break()
del(src)
if (2)
if (prob(50))
@@ -40,19 +36,13 @@
/obj/structure/lamarr/blob_act()
if (prob(75))
new /obj/item/weapon/shard( src.loc )
if (occupied)
var/obj/effect/alien/facehugger/A = new /obj/effect/alien/facehugger( src.loc )
A.lamarr = 1
A.name = "Lamarr"
occupied = 0
Break()
del(src)
/obj/structure/lamarr/meteorhit(obj/O as obj)
new /obj/item/weapon/shard( src.loc )
var/obj/effect/alien/facehugger/A = new /obj/effect/alien/facehugger( src.loc )
A.lamarr = 1
A.name = "Lamarr"
Break()
del(src)
@@ -63,11 +53,7 @@
src.destroyed = 1
new /obj/item/weapon/shard( src.loc )
playsound(src, "shatter", 70, 1)
var/obj/effect/alien/facehugger/A = new /obj/effect/alien/facehugger( src.loc )
A.lamarr = 1
A.name = "Lamarr"
occupied = 0
update_icon()
Break()
else
playsound(src.loc, 'Glasshit.ogg', 75, 1)
return
@@ -99,4 +85,13 @@
O << text("\red [] kicks the lab cage.", usr)
src.health -= 2
healthcheck()
return
return
/obj/structure/lamarr/proc/Break()
if(occupied)
var/obj/item/clothing/mask/facehugger/A = new /obj/item/clothing/mask/facehugger( src.loc )
A.sterile = 1
A.name = "Lamarr"
occupied = 0
update_icon()
return
-3
View File
@@ -1402,9 +1402,6 @@ turf/simulated/floor/return_siding_icon_state()
for(var/obj/mecha/M in src)//Mecha are not gibbed but are damaged.
spawn(0)
M.take_damage(100, "brute")
for(var/obj/effect/alien/facehugger/M in src)//These really need to be mobs.
spawn(0)
M.death()
for(var/obj/effect/critter/M in src)
spawn(0)
M.Die()
@@ -30,6 +30,7 @@ Doesn't work on other aliens/AI.*/
new /obj/effect/alien/weeds/node(loc)
return
/*
/mob/living/carbon/alien/humanoid/verb/call_to()
set name = "Call facehuggers (5)"
set desc = "Makes all nearby facehuggers follow you"
@@ -41,7 +42,7 @@ Doesn't work on other aliens/AI.*/
F.call_to(src)
emote("roar")
return
*/
/mob/living/carbon/alien/humanoid/verb/whisp(mob/M as mob in oview())
set name = "Whisper (10)"
set desc = "Whisper to someone"
@@ -165,14 +166,14 @@ I kind of like the right click only--the window version can get a little confusi
if(target_vent)
for(var/mob/O in viewers(src, null))
O.show_message(text("<B>[src] scrambles into the ventillation ducts!</B>"), 1)
var/list/huggers = list()
for(var/obj/effect/alien/facehugger/F in view(3, src))
if(istype(F, /obj/effect/alien/facehugger))
huggers.Add(F)
// var/list/huggers = list()
// for(var/obj/effect/alien/facehugger/F in view(3, src))
// if(istype(F, /obj/effect/alien/facehugger))
// huggers.Add(F)
loc = vent_found
for(var/obj/effect/alien/facehugger/F in huggers)
F.loc = vent_found
// for(var/obj/effect/alien/facehugger/F in huggers)
// F.loc = vent_found
var/travel_time = get_dist(loc, target_vent.loc)
spawn(round(travel_time/2))//give sound warning to anyone near the target vent
@@ -185,8 +186,8 @@ I kind of like the right click only--the window version can get a little confusi
target_vent = vent_found //travel back. No additional time required.
src << "\red The vent you were heading to appears to be welded."
loc = target_vent.loc
for(var/obj/effect/alien/facehugger/F in huggers)
F.loc = loc
// for(var/obj/effect/alien/facehugger/F in huggers)
// F.loc = loc
else
src << "\green You need to remain still while entering a vent."
@@ -7,7 +7,7 @@
src.real_name = src.name
spawn (1)
src.verbs += /mob/living/carbon/alien/humanoid/proc/corrode_target
src.verbs -= /mob/living/carbon/alien/humanoid/verb/call_to
// src.verbs -= /mob/living/carbon/alien/humanoid/verb/call_to
src.stand_icon = new /icon('alien.dmi', "aliend_s")
src.lying_icon = new /icon('alien.dmi', "aliend_l")
src.icon = src.stand_icon
@@ -64,7 +64,7 @@
/mob/living/carbon/alien/humanoid/special/proc/remove_special_verbs()
verbs -= /mob/living/carbon/alien/humanoid/verb/plant
verbs -= /mob/living/carbon/alien/humanoid/verb/call_to
// verbs -= /mob/living/carbon/alien/humanoid/verb/call_to
verbs -= /mob/living/carbon/alien/humanoid/verb/whisp
verbs -= /mob/living/carbon/alien/humanoid/verb/transfer_plasma
verbs -= /mob/living/carbon/alien/humanoid/verb/corrode
+1
View File
@@ -211,6 +211,7 @@
if(S.parent == mob)
S.loc = mob.loc
moving = 0
return .
return