- Xenos suit and helm (completely obscuring, and almost indistinguishable from drones) (admin spawned only for now). 
- Facehuggers now have different icon states for being thrown and after impregnation. 
- New death, unconscious and sleeping icons for aliens. 
- New icon (and projectile type) for neuroxotin. 
- New infection overlay images for telling aliens about pregnant humans (3 icons, showing the progression of the infestation). 
- New system for handling alien impregnation (alien embryos are an object inside the mob, instead of a disease). 
- Players can be operated surgically to remove the alien embryos (targetting the chest: scalpel, surgical saw, hemostat, retractors. If the embryo is nearly fully developed, it might come out alive though. 
- Corgis can now get impregnated. 
- There is a short animated overlay of a chestburster when it comes time to burst chests. 
- Alien larva now have three different icon sets, depending on their growth (25% they are bloody and pale, 25% - 75% they are pale, 75% onwards they are deep red).


Fixed up table smashing, and added rack smashing in the same way.
Added new north/south facing for the large alien queen.
Updated the changelog.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@5493 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
petethegoat@gmail.com
2013-01-08 16:30:45 +00:00
parent 6ae1348790
commit ef8369409e
37 changed files with 567 additions and 121 deletions
@@ -185,9 +185,10 @@ Des: Gives the client of the alien an image on each infected mob.
----------------------------------------*/
/mob/living/carbon/alien/proc/AddInfectionImages()
if (client)
for (var/mob/living/carbon/C in mob_list)
for (var/mob/living/C in mob_list)
if(C.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected")
var/obj/item/alien_embryo/A = locate() in C
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]")
client.images += I
return
@@ -199,11 +200,10 @@ Des: Removes all infected images from the alien.
/mob/living/carbon/alien/proc/RemoveInfectionImages()
if (client)
for(var/image/I in client.images)
if(I.icon_state == "infected")
if(dd_hasprefix_case(I.icon_state, "infected"))
del(I)
return
#undef HEAT_DAMAGE_LEVEL_1
#undef HEAT_DAMAGE_LEVEL_2
#undef HEAT_DAMAGE_LEVEL_3
@@ -142,7 +142,7 @@ Doesn't work on other aliens/AI.*/
if(!istype(U, /turf))
return
var/obj/item/projectile/energy/dart/A = new /obj/item/projectile/energy/dart(usr.loc)
var/obj/item/projectile/energy/neurotoxin/A = new /obj/item/projectile/energy/neurotoxin(usr.loc)
A.current = U
A.yo = U.y - T.y
@@ -9,6 +9,7 @@
O.show_message("<B>[src]</B> lets out a waning guttural screech, green blood bubbling from its maw...", 1)
update_canmove()
if(client) blind.layer = 0
update_icons()
tod = worldtime2text() //weasellos time of death patch
if(mind) mind.store_memory("Time of death: [tod]", 0)
@@ -359,6 +359,8 @@
//Other
if(stunned)
AdjustStunned(-1)
if(!stunned)
update_icons()
if(weakened)
weakened = max(weakened-1,0) //before you get mad Rockdtben: I done this so update_canmove isn't called multiple times
@@ -14,9 +14,21 @@
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
update_hud() //TODO: remove the need for this to be here
overlays.Cut()
if(lying)
if(resting) icon_state = "alien[caste]_sleep"
else icon_state = "alien[caste]_l"
if(stat == DEAD)
//If we mostly took damage from fire
if(fireloss > 125)
icon_state = "alien[caste]_husked"
else
icon_state = "alien[caste]_dead"
for(var/image/I in overlays_lying)
overlays += I
else if(lying)
if(resting)
icon_state = "alien[caste]_sleep"
else if(stat == UNCONSCIOUS)
icon_state = "alien[caste]_unconscious"
else
icon_state = "alien[caste]_l"
for(var/image/I in overlays_lying)
overlays += I
else
@@ -2,7 +2,7 @@
if(stat == DEAD) return
if(healths) healths.icon_state = "health6"
stat = DEAD
icon_state = "larva_l"
icon_state = "larva_dead"
if(!gibbed)
update_canmove()
@@ -88,6 +88,9 @@
if("jump")
message = "<B>The [src.name]</B> jumps!"
m_type = 1
if("hiss_")
message = "<B>The [src.name]</B> hisses softly."
m_type = 1
if("collapse")
Paralyse(2)
message = text("<B>[]</B> collapses!", src)
@@ -1,7 +1,7 @@
/mob/living/carbon/alien/larva
name = "alien larva"
real_name = "alien larva"
icon_state = "larva"
icon_state = "larva0"
pass_flags = PASSTABLE
maxHealth = 25
@@ -11,6 +11,7 @@
var/amount_grown = 0
var/max_grown = 200
var/time_of_birth
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/larva/New()
@@ -55,6 +55,9 @@
for(var/obj/item/weapon/grab/G in src)
G.process()
//some kind of bug in canmove() isn't properly calling update_icons, so this is here as a placeholder
update_icons()
if(client)
handle_regular_hud_updates()
@@ -226,7 +229,7 @@
return 1
//UNCONSCIOUS. NO-ONE IS HOME
if( (getOxyLoss() > 50) || (0 > health) )
if( (getOxyLoss() > 25) || (0 > health) )
//if( health <= 20 && prob(1) )
// spawn(0)
// emote("gasp")
@@ -244,7 +247,7 @@
stat = UNCONSCIOUS
if( prob(10) && health )
spawn(0)
emote("hiss")
emote("hiss_")
//CONSCIOUS
else
stat = CONSCIOUS
@@ -28,12 +28,16 @@
if(stat != CONSCIOUS)
return
if(handcuffed || legcuffed)
src << "\red You cannot evolve when you are cuffed."
if(amount_grown >= max_grown) //TODO ~Carn
src << "\green You are growing into a beautiful alien! It is time to choose a caste."
src << "\green There are three to choose from:"
src << "\green <B>Hunters</B> are strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves."
src << "\green <B>Sentinels</B> are tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters."
src << "\green <B>Drones</B> are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen."
//green is impossible to read, so i made these blue and changed the formatting slightly
src << "\blue <b>You are growing into a beautiful alien! It is time to choose a caste.</b>"
src << "\blue There are three to choose from:"
src << "<B>Hunters</B> \blue are strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves."
src << "<B>Sentinels</B> \blue are tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters."
src << "<B>Drones</B> \blue are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen."
var/alien_caste = alert(src, "Please choose which alien caste you shall belong to.",,"Hunter","Sentinel","Drone")
var/mob/living/carbon/alien/humanoid/new_xeno
@@ -1 +1,22 @@
//No special icons processing
/mob/living/carbon/alien/larva/regenerate_icons()
overlays = list()
update_icons()
/mob/living/carbon/alien/larva/update_icons()
var/state = 0
if(amount_grown > 150)
state = 2
else if(amount_grown > 50)
state = 1
if(stat == DEAD)
icon_state = "larva[state]_dead"
else if (handcuffed || legcuffed)
icon_state = "larva[state]_cuff"
else if (stunned)
icon_state = "larva[state]_stun"
else if(lying || resting)
icon_state = "larva[state]_sleep"
else
icon_state = "larva[state]"
@@ -0,0 +1,154 @@
// This is to replace the previous datum/disease/alien_embryo for slightly improved handling and maintainability
// It functions almost identically (see code/datums/diseases/alien_embryo.dm)
/obj/item/alien_embryo
name = "alien embryo"
desc = "All slimy and yuck."
icon = 'icons/mob/alien.dmi'
icon_state = "larva0_dead"
var/mob/living/affected_mob
var/stage = 0
/obj/item/alien_embryo/New()
if(istype(loc, /mob/living))
affected_mob = loc
processing_objects.Add(src)
spawn(0)
AddInfectionImages(affected_mob)
else
del(src)
/obj/item/alien_embryo/Del()
if(affected_mob)
affected_mob.status_flags &= ~(XENO_HOST)
spawn(0)
RemoveInfectionImages(affected_mob)
..()
/obj/item/alien_embryo/process()
if(loc != affected_mob)
affected_mob.status_flags &= ~(XENO_HOST)
processing_objects.Remove(src)
affected_mob = null
spawn(0)
RemoveInfectionImages(affected_mob)
return
if(stage < 5 && prob(3))
stage++
spawn(0)
RefreshInfectionImage(affected_mob)
switch(stage)
if(2, 3)
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(1))
affected_mob << "\red Your throat feels sore."
if(prob(1))
affected_mob << "\red Mucous runs down the back of your throat."
if(4)
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(2))
affected_mob << "\red Your muscles ache."
if(prob(20))
affected_mob.take_organ_damage(1)
if(prob(2))
affected_mob << "\red Your stomach hurts."
if(prob(20))
affected_mob.adjustToxLoss(1)
affected_mob.updatehealth()
if(5)
affected_mob << "\red You feel something tearing its way out of your stomach..."
affected_mob.adjustToxLoss(10)
affected_mob.updatehealth()
if(prob(50))
AttemptGrow()
/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1)
var/list/candidates = get_alien_candidates()
var/picked = null
// To stop clientless larva, we will check that our host has a client
// if we find no ghosts to become the alien. If the host has a client
// he will become the alien but if he doesn't then we will set the stage
// to 2, so we don't do a process heavy check everytime.
if(candidates.len)
picked = pick(candidates)
else if(affected_mob.client)
picked = affected_mob.key
else
stage = 4 // Let's try again later.
return
if(affected_mob.lying)
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_lie")
else
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_stand")
spawn(6)
var/mob/living/carbon/alien/larva/new_xeno = new(affected_mob.loc)
new_xeno.key = picked
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention
if(gib_on_success)
affected_mob.gib()
del(src)
/*----------------------------------------
Proc: RefreshInfectionImage()
Des: Removes all infection images from aliens and places an infection image on all infected mobs for aliens.
----------------------------------------*/
/obj/item/alien_embryo/proc/RefreshInfectionImage()
spawn(0)
for (var/mob/living/carbon/alien/alien in player_list)
if (alien.client)
for(var/image/I in alien.client.images)
if(dd_hasprefix_case(I.icon_state, "infected"))
del(I)
for (var/mob/living/carbon/alien/alien in player_list)
if (alien.client)
for (var/mob/living/carbon/C in mob_list)
if(C)
if (C.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
alien.client.images += I
for (var/mob/living/simple_animal/corgi/C in mob_list)
if(C)
if (C.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
alien.client.images += I
return
/*----------------------------------------
Proc: AddInfectionImages(C)
Des: Checks if the passed mob (C) is infected with the alien egg, then gives each alien client an infected image at C.
----------------------------------------*/
/obj/item/alien_embryo/proc/AddInfectionImages(var/mob/living/C)
if (C)
for (var/mob/living/carbon/alien/alien in player_list)
if (alien.client)
if (C.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
alien.client.images += I
return
/*----------------------------------------
Proc: RemoveInfectionImage(C)
Des: Removes the alien infection image from all aliens in the world located in passed mob (C).
----------------------------------------*/
/obj/item/alien_embryo/proc/RemoveInfectionImages(var/mob/living/C)
if (C)
for (var/mob/living/carbon/alien/alien in player_list)
if (alien.client)
for(var/image/I in alien.client.images)
if(I.loc == C)
if(dd_hasprefix_case(I.icon_state, "infected"))
del(I)
return
@@ -94,12 +94,22 @@ var/const/MAX_ACTIVE_TIME = 400
if(CanHug(AM))
Attach(AM)
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]_thrown"
spawn(15)
if(icon_state == "[initial(icon_state)]_thrown")
icon_state = "[initial(icon_state)]"
/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom)
Attach(hit_atom)
return
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]"
Attach(hit_atom)
/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
if(!iscarbon(M) || isalien(M))
if( (!iscorgi(M) && !iscarbon(M)) || isalien(M))
return
if(attached)
return
@@ -114,49 +124,61 @@ var/const/MAX_ACTIVE_TIME = 400
if(stat != CONSCIOUS) return
if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
var/mob/living/carbon/target = L
L.visible_message("\red \b [src] leaps at [L]'s face!")
target.visible_message("\red \b [src] leaps at [target]'s face!")
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.head && H.head.flags & HEADCOVERSMOUTH)
H.visible_message("\red \b [src] smashes against [H]'s [H.head]!")
Die()
return
if(target.wear_mask)
if(prob(20)) return
var/obj/item/clothing/W = target.wear_mask
if(!W.canremove) return
target.drop_from_inventory(W)
if(iscarbon(M))
var/mob/living/carbon/target = L
target.visible_message("\red \b [src] tears [W] off of [target]'s face!")
if(target.wear_mask)
if(prob(20)) return
var/obj/item/clothing/W = target.wear_mask
if(!W.canremove) return
target.drop_from_inventory(W)
target.equip_to_slot(src, slot_wear_mask)
target.visible_message("\red \b [src] tears [W] off of [target]'s face!")
target.equip_to_slot(src, slot_wear_mask)
if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
else if (iscorgi(M))
var/mob/living/simple_animal/corgi/C = M
src.loc = C
C.facehugger = src
C.wear_mask = src
//C.regenerate_icons()
GoIdle() //so it doesn't jump the people that tear it off
if(!sterile) target.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
Impregnate(target)
Impregnate(L)
return
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/carbon/target as mob)
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob)
if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something
return
if(!sterile)
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.status_flags |= XENO_HOST
break
//target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
new /obj/item/alien_embryo(target)
target.status_flags |= XENO_HOST
target.visible_message("\red \b [src] falls limp after violating [target]'s face!")
Die()
icon_state = "[initial(icon_state)]_impregnated"
if(iscorgi(target))
var/mob/living/simple_animal/corgi/C = target
src.loc = get_turf(C)
C.facehugger = null
else
target.visible_message("\red \b [src] violates [target]'s face!")
return
@@ -204,6 +226,9 @@ var/const/MAX_ACTIVE_TIME = 400
/proc/CanHug(var/mob/M)
if(iscorgi(M))
return 1
if(!iscarbon(M) || isalien(M))
return 0
var/mob/living/carbon/C = M
@@ -211,4 +236,4 @@ var/const/MAX_ACTIVE_TIME = 400
var/mob/living/carbon/human/H = C
if(H.head && H.head.flags & HEADCOVERSMOUTH)
return 0
return 1
return 1
@@ -5,6 +5,7 @@
var/brain_op_stage = 0.0
var/eye_op_stage = 0.0
var/appendix_op_stage = 0.0
var/alien_op_stage = 0.0
var/antibodies = 0
@@ -20,6 +20,7 @@
see_in_dark = 5
var/obj/item/inventory_head
var/obj/item/inventory_back
var/facehugger
/mob/living/simple_animal/corgi/Life()
..()
@@ -375,7 +376,7 @@
if(health <= 0)
head_icon_state += "2"
var/icon/head_icon = icon('icons/mob/corgi_head.dmi',head_icon_state)
var/icon/head_icon = image('icons/mob/corgi_head.dmi',head_icon_state)
if(head_icon)
overlays += head_icon
@@ -384,9 +385,16 @@
if(health <= 0)
back_icon_state += "2"
var/icon/back_icon = icon('icons/mob/corgi_back.dmi',back_icon_state)
var/icon/back_icon = image('icons/mob/corgi_back.dmi',back_icon_state)
if(back_icon)
overlays += back_icon
if(facehugger)
if(istype(src, /mob/living/simple_animal/corgi/puppy))
overlays += image('icons/mob/mask.dmi',"facehugger_corgipuppy")
else
overlays += image('icons/mob/mask.dmi',"facehugger_corgi")
return