diff --git a/code/_global_vars/mobs.dm b/code/_global_vars/mobs.dm
index 7e60dc71ea..5041c7e03a 100644
--- a/code/_global_vars/mobs.dm
+++ b/code/_global_vars/mobs.dm
@@ -6,3 +6,4 @@ GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client
GLOBAL_LIST_EMPTY(clients)
GLOBAL_LIST_EMPTY(players_by_zlevel)
GLOBAL_LIST_EMPTY(round_text_log)
+GLOBAL_LIST_EMPTY(ghost_mob_list) //List of all ghosts, including clientless. Excludes /mob/new_player
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 72f88c6a1b..fe297004e4 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -229,7 +229,7 @@ var/list/gamemode_cache = list()
// 15, 45, 70 minutes respectively
var/static/list/event_delay_upper = list(EVENT_LEVEL_MUNDANE = 9000, EVENT_LEVEL_MODERATE = 27000, EVENT_LEVEL_MAJOR = 42000)
- var/static/aliens_allowed = 0
+ var/static/aliens_allowed = 1 //This not only allows the natural spawning of xenos, but also the ability to lay eggs. Xenomorphs cannot lay eggs if this is 0
var/static/ninjas_allowed = 0
var/static/abandon_allowed = 1
var/static/ooc_allowed = 1
diff --git a/code/game/objects/effects/alien/alien egg.dm b/code/game/objects/effects/alien/alien egg.dm
new file mode 100644
index 0000000000..3d0b886842
--- /dev/null
+++ b/code/game/objects/effects/alien/alien egg.dm
@@ -0,0 +1,96 @@
+#define MAX_PROGRESS 100
+
+/obj/structure/alien/egg
+ desc = "It looks like a weird egg."
+ name = "egg"
+ icon_state = "egg_growing"
+ density = 0
+ anchored = 1
+ var/progress = 0
+
+/obj/structure/alien/egg/Initialize()
+ . = ..()
+ START_PROCESSING(SSobj, src)
+
+/obj/structure/alien/egg/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ . = ..()
+
+/obj/structure/alien/egg/CanUseTopic(var/mob/user)
+ return isobserver(user) ? STATUS_INTERACTIVE : STATUS_CLOSE
+
+/obj/structure/alien/egg/Topic(href, href_list)
+ if(..())
+ return 1
+
+ if(href_list["spawn"])
+ attack_ghost(usr)
+
+/obj/structure/alien/egg/process()
+ progress++
+ if(progress >= MAX_PROGRESS)
+ for(var/mob/observer/ghost/O in GLOB.ghost_mob_list)
+ if(O.client && O.client.prefs && (BE_ALIEN))
+ to_chat(O, "An alien is ready to hatch! ([ghost_follow_link(src, O)]) (spawn)")
+ STOP_PROCESSING(SSobj, src)
+ update_icon()
+
+/obj/structure/alien/egg/update_icon()
+ if(progress == -1)
+ icon_state = "egg_hatched"
+ else if(progress < MAX_PROGRESS)
+ icon_state = "egg_growing"
+ else
+ icon_state = "egg"
+
+/obj/structure/alien/egg/attack_ghost(var/mob/observer/ghost/user)
+ if(progress == -1) //Egg has been hatched.
+ return
+
+ if(progress < MAX_PROGRESS)
+ to_chat(user, "\The [src] has not yet matured.")
+ return
+
+ if(!user.MayRespawn(1))
+ return
+
+ // Check for bans properly.
+ if(jobban_isbanned(user, MODE_XENOMORPH))
+ to_chat(user, "You are banned from playing a Xenomorph.")
+ return
+
+ var/confirm = alert(user, "Are you sure you want to join as a Xenomorph larva?", "Become Larva", "No", "Yes")
+
+ if(!src || confirm != "Yes")
+ return
+
+ if(!user || !user.ckey)
+ return
+
+ if(progress == -1) //Egg has been hatched.
+ to_chat(user, "Too slow...")
+ return
+
+ flick("egg_opening",src)
+ progress = -1 // No harvesting pls.
+ sleep(5)
+
+ if(!src || !user)
+ visible_message("\The [src] writhes with internal motion, but nothing comes out.")
+ progress = MAX_PROGRESS // Someone else can have a go.
+ return // What a pain.
+
+ // Create the mob, transfer over key.
+ var/mob/living/carbon/alien/larva/larva = new(get_turf(src))
+ larva.ckey = user.ckey
+ spawn(-1)
+ if(user) qdel(user) // Remove the keyless ghost if it exists.
+
+ visible_message("\The [src] splits open with a wet slithering noise, and \the [larva] writhes free!")
+
+ // Turn us into a hatched egg.
+ name = "hatched alien egg"
+ desc += " This one has hatched."
+ update_icon()
+
+#undef MAX_PROGRESS
diff --git a/code/game/objects/effects/alien/alien.dm b/code/game/objects/effects/alien/alien.dm
new file mode 100644
index 0000000000..0af2c3801e
--- /dev/null
+++ b/code/game/objects/effects/alien/alien.dm
@@ -0,0 +1,62 @@
+/obj/structure/alien
+ name = "alien thing"
+ desc = "There's something alien about this."
+ icon = 'icons/mob/alien.dmi'
+ layer = ABOVE_JUNK_LAYER
+ var/health = 50
+
+/obj/structure/alien/proc/healthcheck()
+ if(health <=0)
+ set_density(0)
+ qdel(src)
+ return
+
+/obj/structure/alien/bullet_act(var/obj/item/projectile/Proj)
+ health -= Proj.damage
+ ..()
+ healthcheck()
+ return
+
+/obj/structure/alien/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ health-=50
+ if(2.0)
+ health-=50
+ if(3.0)
+ if (prob(50))
+ health-=50
+ else
+ health-=25
+ healthcheck()
+ return
+
+/obj/structure/alien/hitby(AM as mob|obj)
+ ..()
+ visible_message("\The [src] was hit by \the [AM].")
+ var/tforce = 0
+ if(ismob(AM))
+ tforce = 10
+ else
+ tforce = AM:throwforce
+ playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
+ health = max(0, health - tforce)
+ healthcheck()
+ ..()
+ return
+
+/obj/structure/alien/attack_generic()
+ attack_hand(usr)
+
+/obj/structure/alien/attackby(var/obj/item/weapon/W, var/mob/user)
+ health = max(0, health - W.force)
+ playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
+ healthcheck()
+ ..()
+ return
+
+/obj/structure/alien/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(air_group) return 0
+ if(istype(mover) && mover.checkpass(PASSGLASS))
+ return !opacity
+ return !density
diff --git a/code/game/objects/effects/alien/aliens.dm b/code/game/objects/effects/alien/aliens.dm
index 836e277872..c377153683 100644
--- a/code/game/objects/effects/alien/aliens.dm
+++ b/code/game/objects/effects/alien/aliens.dm
@@ -4,7 +4,6 @@
* Resin
* Weeds
* Acid
- * Egg
*/
/*
@@ -420,130 +419,3 @@
if(0 to 1)
visible_message("[src.target] begins to crumble under the acid!")
spawn(rand(150, 200)) tick()
-
-/*
- * Egg
- */
-/var/const //for the status var
- BURST = 0
- BURSTING = 1
- GROWING = 2
- GROWN = 3
-
- 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" // So the egg looks 'grown', even though it's not.
- icon_state = "egg"
- density = 0
- anchored = 1
-
- var/health = 100
- var/status = BURST //can be GROWING, GROWN or BURST; all mutually exclusive
-
-/obj/effect/alien/egg/New()
-/*
- if(config.aliens_allowed)
- ..()
- spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
- Grow()
- else
- qdel(src)
-*/
-/obj/effect/alien/egg/attack_hand(user as mob)
-
- var/mob/living/carbon/M = user
- if(!istype(M) || !(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs))
- return attack_hand(user)
-
- switch(status)
- if(BURST)
- to_chat(user, "You clear the hatched egg.")
- qdel(src)
- return
-/* if(GROWING)
- to_chat(user, "The child is not developed yet.")
- return
- if(GROWN)
- to_chat(user, "You retrieve the child.")
- Burst(0)
- return
-
-/obj/effect/alien/egg/proc/GetFacehugger() // Commented out for future edit.
- return locate(/obj/item/clothing/mask/facehugger) in contents
-
-/obj/effect/alien/egg/proc/Grow()
- icon_state = "egg"
-// status = GROWN
- status = BURST
-// new /obj/item/clothing/mask/facehugger(src)
- return
-*/
-/obj/effect/alien/egg/proc/Burst(var/kill = 1) //drops and kills the hugger if any is remaining
- if(status == GROWN || status == GROWING)
-// var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
- icon_state = "egg_hatched"
-/* flick("egg_opening", src)
- status = BURSTING
- spawn(15)
- status = BURST
- child.loc = get_turf(src)
-
- if(kill && istype(child))
- child.Die()
- else
- for(var/mob/M in range(1,src))
- if(CanHug(M))
- child.Attach(M)
- break
-*/
-/obj/effect/alien/egg/bullet_act(var/obj/item/projectile/Proj)
- health -= Proj.damage
- ..()
- healthcheck()
- return
-
-/obj/effect/alien/egg/attack_generic(var/mob/user, var/damage, var/attack_verb)
- visible_message("[user] [attack_verb] the [src]!")
- user.do_attack_animation(src)
- health -= damage
- healthcheck()
- return
-
-/obj/effect/alien/egg/take_damage(var/damage)
- health -= damage
- healthcheck()
- return
-
-
-/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user)
- if(health <= 0)
- return
- if(W.attack_verb.len)
- src.visible_message("\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]")
- else
- src.visible_message("\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]")
- var/damage = W.force / 4.0
-
- if(istype(W, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = W
-
- if(WT.remove_fuel(0, user))
- damage = 15
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
-
- src.health -= damage
- src.healthcheck()
-
-
-/obj/effect/alien/egg/proc/healthcheck()
- if(health <= 0)
- Burst()
-
-/obj/effect/alien/egg/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > 500 + T0C)
- health -= 5
- healthcheck()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 149eba55eb..35be735339 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -40,9 +40,9 @@
/mob/living/carbon/alien/u_equip(obj/item/W as obj)
return
-/mob/living/carbon/alien/Stat()
+/*/mob/living/carbon/alien/Stat() //Commented out because this doesn't work properly for larva, when it should. Will probably give Diona their own kind of they don't have one
..()
- stat(null, "Progress: [amount_grown]/[max_grown]")
+ stat(null, "Progress: [amount_grown]/[max_grown]") */
/mob/living/carbon/alien/restrained()
return 0
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index e39f66c479..21a8a4a2d3 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -5,9 +5,10 @@
speak_emote = list("hisses")
icon_state = "larva"
language = "Hivemind"
- maxHealth = 25
+ maxHealth = 50 //Larva can gain a little more health on weeds/phoron to make them just a little harder to kill
health = 25
faction = "xeno"
+ max_grown = 325 //Since xenos can reproduce without people now I decided to drastically increase the growth time
/mob/living/carbon/alien/larva/Initialize()
. = ..()
diff --git a/code/modules/mob/living/carbon/alien/larva/progression.dm b/code/modules/mob/living/carbon/alien/larva/progression.dm
index 4e9c15552f..9a9f9fb54d 100644
--- a/code/modules/mob/living/carbon/alien/larva/progression.dm
+++ b/code/modules/mob/living/carbon/alien/larva/progression.dm
@@ -1,3 +1,8 @@
+/mob/living/carbon/alien/larva/Stat() //Oh thank god we can see how close we are to full grown now
+ . = ..()
+ if(. && statpanel("Status"))
+ stat("Growth", "[round(amount_grown)]/[max_grown]")
+
/mob/living/carbon/alien/larva/confirm_evolution()
to_chat(src, "You are growing into a beautiful alien! It is time to choose a caste.")
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index 43bcdde499..7b023b229c 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -28,7 +28,7 @@
var/rads = radiation/25
radiation -= rads
- adjust_nutrition(rads)
+ /*adjust_nutrition(rads)*/ //Commented out to prevent xeno/diona obesity, it was a real problem
heal_overall_damage(rads,rads)
adjustOxyLoss(-(rads))
adjustToxLoss(-(rads))
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 17c2e87969..097ae440b3 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1192,6 +1192,11 @@
maxHealth = species.total_health
hunger_rate = species.hunger_factor //VOREStation Add
+ default_pixel_x = initial(pixel_x) + species.pixel_offset_x
+ default_pixel_y = initial(pixel_y) + species.pixel_offset_y
+ pixel_x = default_pixel_x
+ pixel_y = default_pixel_y
+
if(LAZYLEN(descriptors))
descriptors = null
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 237428e24b..0192b711b3 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -18,6 +18,9 @@
var/fire_icon_state = "humanoid" // The icon_state used inside OnFire.dmi for when on fire.
var/suit_storage_icon = 'icons/mob/belt_mirror.dmi' // Icons used for worn items in suit storage slot.
+ var/pixel_offset_x = 0 // Used for offsetting large icons.
+ var/pixel_offset_y = 0 // Used for offsetting large icons.
+
// Damage overlay and masks.
var/damage_overlays = 'icons/mob/human_races/masks/dam_human.dmi'
var/damage_mask = 'icons/mob/human_races/masks/dam_mask_human.dmi'
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm
deleted file mode 100644
index 59ba73446d..0000000000
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm
+++ /dev/null
@@ -1,161 +0,0 @@
-// 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 //Commented out as reference for future reproduction methods, or addition later.
- 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
- START_PROCESSING(SSobj, src)
- spawn(0)
- AddInfectionImages(affected_mob)
- else
- qdel(src)
-
-/obj/item/alien_embryo/Destroy()
- if(affected_mob)
- affected_mob.status_flags &= ~(XENO_HOST)
- spawn(0)
- RemoveInfectionImages(affected_mob)
- ..()
-
-/obj/item/alien_embryo/process()
- if(!affected_mob) return
- if(loc != affected_mob)
- affected_mob.status_flags &= ~(XENO_HOST)
- STOP_PROCESSING(SSobj, src)
- spawn(0)
- RemoveInfectionImages(affected_mob)
- affected_mob = null
- 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))
- to_chat(affected_mob, "Your throat feels sore.")
- if(prob(1))
- to_chat(affected_mob, "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))
- to_chat(affected_mob, " Your muscles ache.")
- if(prob(20))
- affected_mob.take_organ_damage(1)
- if(prob(2))
- to_chat(affected_mob, "Your stomach hurts.")
- if(prob(20))
- affected_mob.adjustToxLoss(1)
- affected_mob.updatehealth()
- if(5)
- to_chat(affected_mob, "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()
- qdel(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()
-
- for(var/mob/living/carbon/alien in player_list)
-
- if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs)
- continue
-
- if(alien.client)
- for(var/image/I in alien.client.images)
- if(dd_hasprefix_case(I.icon_state, "infected"))
- qdel(I)
- for(var/mob/living/L in mob_list)
- if(iscorgi(L) || iscarbon(L))
- if(L.status_flags & XENO_HOST)
- var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[stage]")
- alien.client.images += I
-
-/*----------------------------------------
-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 in player_list)
-
- if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs)
- continue
-
- 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
-
-/*----------------------------------------
-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 in player_list)
-
- if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs)
- continue
-
- if(alien.client)
- for(var/image/I in alien.client.images)
- if(I.loc == C)
- if(dd_hasprefix_case(I.icon_state, "infected"))
- qdel(I)
-*/
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
deleted file mode 100644
index 4bfffdfa47..0000000000
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
+++ /dev/null
@@ -1,221 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-//TODO: Make these simple_mobs
-/* //Commented out as reference for future reproduction methods, or addition later if needed. - Mech
-var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
-var/const/MAX_IMPREGNATION_TIME = 150
-
-var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle
-var/const/MAX_ACTIVE_TIME = 400
-
-/obj/item/clothing/mask/facehugger
- name = "alien"
- desc = "It has some sort of a tube at the end of its tail."
- icon = 'icons/mob/alien.dmi'
- icon_state = "facehugger"
- item_state = "facehugger"
- w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4
- body_parts_covered = FACE|EYES
- throw_range = 5
-
- var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
- var/sterile = 0
- var/strength = 5
- var/attached = 0
-
-/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
-
- if((stat == CONSCIOUS && !sterile))
- if(Attach(user))
- return
-
- ..()
-
-/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
- ..()
- user.drop_from_inventory(src)
- Attach(M)
-
-/obj/item/clothing/mask/facehugger/New()
- if(config.aliens_allowed)
- ..()
- else
- qdel(src)
-
-/obj/item/clothing/mask/facehugger/examine(mob/user)
- ..(user)
- switch(stat)
- if(DEAD,UNCONSCIOUS)
- to_chat(user, "[src] is not moving.")
- if(CONSCIOUS)
- to_chat(user, "[src] seems to be active.")
- if (sterile)
- to_chat(user, "It looks like the proboscis has been removed.")
- return
-
-/obj/item/clothing/mask/facehugger/attackby(obj/item/I, mob/user)
- if(I.force)
- user.do_attack_animation(src)
- Die()
- return
-
-/obj/item/clothing/mask/facehugger/bullet_act()
- Die()
- return
-
-/obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > T0C+80)
- Die()
- return
-
-/obj/item/clothing/mask/facehugger/equipped(mob/M)
- ..()
- Attach(M)
-
-/obj/item/clothing/mask/facehugger/Crossed(atom/target)
- HasProximity(target)
- return
-
-/obj/item/clothing/mask/facehugger/on_found(mob/finder as mob)
- if(stat == CONSCIOUS)
- HasProximity(finder)
- return 1
- return
-
-/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
- 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)
- ..()
- if(stat == CONSCIOUS)
- icon_state = "[initial(icon_state)]"
- throwing = 0
- GoIdle(30,100) //stunned for a few seconds - allows throwing them to be useful for positioning but not as an offensive action (unless you're setting up a trap)
-
-/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
-
- if((!iscorgi(M) && !iscarbon(M)))
- return
-
- if(attached)
- return
-
- var/mob/living/carbon/C = M
- if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs)
- return
-
-
- attached++
- spawn(MAX_IMPREGNATION_TIME)
- attached = 0
-
- var/mob/living/L = M //just so I don't need to use :
-
- if(loc == L) return
- if(stat != CONSCIOUS) return
- if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
-
- L.visible_message(" [src] leaps at [L]'s face!")
-
- if(iscarbon(M))
- var/mob/living/carbon/target = L
-
- 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.visible_message(" [src] tears [W] off of [target]'s face!")
-
- target.equip_to_slot(src, slot_wear_mask)
- target.contents += src // Monkey sanity check - Snapshot
-
- if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
-
- GoIdle() //so it doesn't jump the people that tear it off
-
- spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
- Impregnate(L)
-
- return
-
-/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)
- new /obj/item/alien_embryo(target)
- target.status_flags |= XENO_HOST
-
- target.visible_message(" [src] falls limp after violating [target]'s face!")
-
- Die()
- icon_state = "[initial(icon_state)]_impregnated"
-
- else
- target.visible_message(" [src] violates [target]'s face!")
- return
-
-/obj/item/clothing/mask/facehugger/proc/GoActive()
- if(stat == DEAD || stat == CONSCIOUS)
- return
-
- stat = CONSCIOUS
- icon_state = "[initial(icon_state)]"
-
- return
-
-/obj/item/clothing/mask/facehugger/proc/GoIdle(var/min_time=MIN_ACTIVE_TIME, var/max_time=MAX_ACTIVE_TIME)
- if(stat == DEAD || stat == UNCONSCIOUS)
- return
-
-/* RemoveActiveIndicators() */
-
- stat = UNCONSCIOUS
- icon_state = "[initial(icon_state)]_inactive"
-
- spawn(rand(min_time,max_time))
- GoActive()
- return
-
-/obj/item/clothing/mask/facehugger/proc/Die()
- if(stat == DEAD)
- return
-
-/* RemoveActiveIndicators() */
-
- icon_state = "[initial(icon_state)]_dead"
- stat = DEAD
-
- src.visible_message("[src] curls up into a ball!")
-
- return
-
-/proc/CanHug(var/mob/M)
-
- if(iscorgi(M))
- return 1
-
- if(!iscarbon(M))
- return 0
-
- var/mob/living/carbon/C = M
- if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs)
- return 0
-
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(H.head && (H.head.body_parts_covered & FACE) && !(H.head.item_flags & FLEXIBLEMATERIAL))
- return 0
- return 1
-*/
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm
index bfeaf73fde..18555a8b45 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm
@@ -88,13 +88,13 @@
verbs -= /mob/living/carbon/human/proc/lay_egg
return
- if(locate(/obj/effect/alien/egg) in get_turf(src))
+ if(locate(/obj/structure/alien/egg) in get_turf(src))
to_chat(src, "There's already an egg here.")
return
if(check_alien_ability(75,1,O_EGG))
visible_message("[src] has laid an egg!")
- new /obj/effect/alien/egg(loc)
+ new /obj/structure/alien/egg(loc)
return
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
index 425a72185c..c537e99b92 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
@@ -10,12 +10,19 @@
hud_type = /datum/hud_data/alien
rarity_value = 3
+ darksight = 10
+
+ pixel_offset_x = -16 //I literally had to make a different form of pixel_x just for this species, fuck my life
+
+
+ icon_template = 'icons/mob/human_races/xenos/template.dmi'
+
has_fine_manipulation = 0
siemens_coefficient = 0
gluttonous = 2
- brute_mod = 0.5 // Hardened carapace.
- burn_mod = 2 // Weak to fire.
+ brute_mod = 0.65 // Hardened carapace.
+ burn_mod = 1.50 // Weak to fire.
warning_low_pressure = 50
hazard_low_pressure = -1
@@ -33,9 +40,13 @@
flesh_color = "#282846"
gibbed_anim = "gibbed-a"
dusted_anim = "dust-a"
- death_message = "lets out a waning guttural screech, green blood bubbling from its maw."
+ death_message = "lets out a piercing multi-toned screech, green blood bubbling from its maw as it ceases."
death_sound = 'sound/voice/hiss6.ogg'
+ damage_overlays = null //They don't have overlays yet, if someone wants to add some then be my guest
+ damage_mask = null
+ blood_mask = null
+
speech_sounds = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
speech_chance = 100
@@ -91,8 +102,8 @@
return FALSE
/datum/species/xenos/hug(var/mob/living/carbon/human/H,var/mob/living/target)
- H.visible_message("[H] caresses [target] with its scythe-like arm.", \
- "You caress [target] with your scythe-like arm.")
+ H.visible_message("[H] caresses [target] with its eldritch arm.", \
+ "You caress [target] with your eldritch arm.")
/datum/species/xenos/handle_post_spawn(var/mob/living/carbon/human/H)
@@ -169,7 +180,7 @@
caste_name = "drone"
weeds_plasma_rate = 15
slowdown = 1
- tail = "xenos_drone_tail"
+ tail = null
rarity_value = 5
icobase = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
@@ -210,7 +221,7 @@
caste_name = "hunter"
slowdown = -2
total_health = 150
- tail = "xenos_hunter_tail"
+ tail = null
icobase = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
@@ -240,7 +251,7 @@
caste_name = "sentinel"
slowdown = 0
total_health = 200
- tail = "xenos_sentinel_tail"
+ tail = null
icobase = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
@@ -269,12 +280,12 @@
/datum/species/xenos/queen
name = SPECIES_XENO_QUEEN
- total_health = 250
+ total_health = 300 //Queen is chonk
weeds_heal_rate = 5
weeds_plasma_rate = 20
caste_name = "queen"
slowdown = 4
- tail = "xenos_queen_tail"
+ tail = null
rarity_value = 10
icobase = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm
index 50f4ce9cc5..6605844253 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm
@@ -27,30 +27,3 @@ proc/create_new_xenomorph(var/alien_caste,var/target)
faction = "xeno"
..(new_loc, SPECIES_XENO_QUEEN)
-// I feel like we should generalize/condense down all the various icon-rendering antag procs.
-/*----------------------------------------
-Proc: AddInfectionImages()
-Des: Gives the client of the alien an image on each infected mob.
-----------------------------------------*/
-/*
-/mob/living/carbon/human/proc/AddInfectionImages()
- if (client)
- for (var/mob/living/C in mob_list)
- if(C.status_flags & XENO_HOST)
- 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
-*/
-/*----------------------------------------
-Proc: RemoveInfectionImages()
-Des: Removes all infected images from the alien.
-----------------------------------------*/
-/*
-/mob/living/carbon/human/proc/RemoveInfectionImages()
- if (client)
- for(var/image/I in client.images)
- if(dd_hasprefix_case(I.icon_state, "infected"))
- qdel(I)
- return
-*/
diff --git a/code/modules/organs/subtypes/xenos.dm b/code/modules/organs/subtypes/xenos.dm
index 1c4cfa6907..26c9a2634f 100644
--- a/code/modules/organs/subtypes/xenos.dm
+++ b/code/modules/organs/subtypes/xenos.dm
@@ -213,3 +213,4 @@
cannot_amputate = 1
thick_skin = TRUE
eye_icon = "blank_eyes"
+ var/vision_flags = SEE_MOBS|SEE_TURFS
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index a6a9a87386..6a31d99103 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -15,47 +15,6 @@
return affected && affected.open == (affected.encased ? 3 : 2)
-//////////////////////////////////////////////////////////////////
-// ALIEN EMBRYO SURGERY //
-////////////////////////////////////////////////////////////////// // Here for future reference incase it's needed. See: Alien_embryo.dm and Alien_facehugger.dm
-/*
-/datum/surgery_step/internal/remove_embryo
- allowed_tools = list(
- /obj/item/weapon/surgical/hemostat = 100, \
- /obj/item/weapon/material/kitchen/utensil/fork = 20
- )
-
- allowed_procs = list(IS_WIRECUTTER = 75)
- blood_level = 2
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/embryo = 0
- for(var/obj/item/alien_embryo/A in target)
- embryo = 1
- break
-
- if (!hasorgans(target))
- return
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected && embryo && affected.open == 3 && target_zone == BP_TORSO
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]."
- var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] rips the larva out of [target]'s ribcage!",
- "You rip the larva out of [target]'s ribcage!")
-
- for(var/obj/item/alien_embryo/A in target)
- A.loc = A.loc.loc
-*/
//////////////////////////////////////////////////////////////////
// CHEST INTERNAL ORGAN SURGERY //
//////////////////////////////////////////////////////////////////
diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi
index f00110275d..757e3f5f96 100644
Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ
diff --git a/icons/mob/human_races/xenos/r_xenos_drone.dmi b/icons/mob/human_races/xenos/r_xenos_drone.dmi
index 19094d66ed..e8bec0b714 100644
Binary files a/icons/mob/human_races/xenos/r_xenos_drone.dmi and b/icons/mob/human_races/xenos/r_xenos_drone.dmi differ
diff --git a/icons/mob/human_races/xenos/r_xenos_hunter.dmi b/icons/mob/human_races/xenos/r_xenos_hunter.dmi
index a6ce545f3a..0c9e3854bf 100644
Binary files a/icons/mob/human_races/xenos/r_xenos_hunter.dmi and b/icons/mob/human_races/xenos/r_xenos_hunter.dmi differ
diff --git a/icons/mob/human_races/xenos/r_xenos_queen.dmi b/icons/mob/human_races/xenos/r_xenos_queen.dmi
index efb5558ac1..a88779a11c 100644
Binary files a/icons/mob/human_races/xenos/r_xenos_queen.dmi and b/icons/mob/human_races/xenos/r_xenos_queen.dmi differ
diff --git a/icons/mob/human_races/xenos/r_xenos_sentinel.dmi b/icons/mob/human_races/xenos/r_xenos_sentinel.dmi
index 5b250c7445..5619ece107 100644
Binary files a/icons/mob/human_races/xenos/r_xenos_sentinel.dmi and b/icons/mob/human_races/xenos/r_xenos_sentinel.dmi differ
diff --git a/icons/mob/human_races/xenos/template.dmi b/icons/mob/human_races/xenos/template.dmi
new file mode 100644
index 0000000000..deb0741319
Binary files /dev/null and b/icons/mob/human_races/xenos/template.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index 0e9bc3113c..d6a64f752a 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1067,6 +1067,8 @@
#include "code\game\objects\effects\spiders_vr.dm"
#include "code\game\objects\effects\step_triggers.dm"
#include "code\game\objects\effects\zone_divider.dm"
+#include "code\game\objects\effects\alien\alien egg.dm"
+#include "code\game\objects\effects\alien\alien.dm"
#include "code\game\objects\effects\alien\aliens.dm"
#include "code\game\objects\effects\chem\chemsmoke.dm"
#include "code\game\objects\effects\chem\coating.dm"