diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index f84c04f531a..435a166f326 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -1512,10 +1512,14 @@
mind.special_role = "Alien"
mind.assigned_role = "Alien"
//XENO HUMANOID
-/mob/living/carbon/alien/humanoid/queen/mind_initialize()
+/mob/living/carbon/alien/humanoid/royal/queen/mind_initialize()
..()
mind.special_role = "Queen"
+/mob/living/carbon/alien/humanoid/royal/praetorian/mind_initialize()
+ ..()
+ mind.special_role = "Praetorian"
+
/mob/living/carbon/alien/humanoid/hunter/mind_initialize()
..()
mind.special_role = "Hunter"
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index cb4d5ace22f..47ddaa84213 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -570,7 +570,7 @@ var/global/list/possible_items_special = list()
continue
captured_amount+=1
for(var/mob/living/carbon/alien/humanoid/M in A)//Aliens are worth twice as much as humans.
- if(istype(M, /mob/living/carbon/alien/humanoid/queen))//Queens are worth three times as much as humans.
+ if(istype(M, /mob/living/carbon/alien/humanoid/royal/queen))//Queens are worth three times as much as humans.
if(M.stat==2)
captured_amount+=1.5
else
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index bc468f7fa35..42ade144ac5 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -121,8 +121,9 @@ var/global/floorIsLava = 0
body += "Observer | "
body += "\[ Alien: Drone, "
body += "Hunter, "
- body += "Queen, "
body += "Sentinel, "
+ body += "Praetorian, "
+ body += "Queen, "
body += "Larva \] "
body += "Human "
body += "\[ slime: Baby, "
@@ -516,7 +517,7 @@ var/global/floorIsLava = 0
usr << "Error: Start Now: Game is in startup, please wait until it has finished."
else
usr << "Error: Start Now: Game has already started."
-
+
return 0
/datum/admins/proc/toggleenter()
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 9b89c0c01e7..83e5b41a4aa 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -383,7 +383,8 @@
if("observer") M.change_mob_type( /mob/dead/observer , null, null, delmob )
if("drone") M.change_mob_type( /mob/living/carbon/alien/humanoid/drone , null, null, delmob )
if("hunter") M.change_mob_type( /mob/living/carbon/alien/humanoid/hunter , null, null, delmob )
- if("queen") M.change_mob_type( /mob/living/carbon/alien/humanoid/queen , null, null, delmob )
+ if("queen") M.change_mob_type( /mob/living/carbon/alien/humanoid/royal/queen , null, null, delmob )
+ if("praetorian") M.change_mob_type( /mob/living/carbon/alien/humanoid/royal/praetorian , null, null, delmob )
if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob )
if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob )
if("human") M.change_mob_type( /mob/living/carbon/human , null, null, delmob )
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index c01bfde1974..859cb12804e 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -208,11 +208,12 @@
usr << "Error: create_xeno(): no suitable candidates."
if(!istext(ckey)) return 0
- var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Hunter","Sentinel","Drone","Larva")
+ var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Praetorian","Hunter","Sentinel","Drone","Larva")
var/obj/effect/landmark/spawn_here = xeno_spawn.len ? pick(xeno_spawn) : pick(latejoin)
var/mob/living/carbon/alien/new_xeno
switch(alien_caste)
- if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen(spawn_here)
+ if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(spawn_here)
+ if("Praetorian") new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(spawn_here)
if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here)
if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here)
if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here)
@@ -262,7 +263,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T)
if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T)
if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(T)
- if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen(T)
+ if("Praetorian") new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(T)
+ if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(T)
else//If we don't know what special role they have, for whatever reason, or they're a larva.
create_xeno(G_found.ckey)
return
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
index a9c09a49ef2..8f12f2b593b 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
@@ -19,25 +19,20 @@
. += 1
/obj/effect/proc_holder/alien/evolve
- name = "Evolve"
- desc = "Produce an interal egg sac capable of spawning children. Only one queen can exist at a time."
+ name = "Evolve to Praetorian"
+ desc = "Praetorian"
plasma_cost = 500
action_icon_state = "alien_evolve_drone"
/obj/effect/proc_holder/alien/evolve/fire(mob/living/carbon/alien/user)
- var/no_queen = 1
- for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list)
- if(!Q.key || !Q.getorgan(/obj/item/organ/internal/brain))
- continue
- no_queen = 0
- if(no_queen)
+ if(!alien_type_present(/mob/living/carbon/alien/humanoid/royal/))
user << "You begin to evolve!"
user.visible_message("[user] begins to twist and contort!")
- var/mob/living/carbon/alien/humanoid/queen/new_xeno = new (user.loc)
+ var/mob/living/carbon/alien/humanoid/royal/praetorian/new_xeno = new (user.loc)
user.mind.transfer_to(new_xeno)
qdel(user)
return 1
else
- user << "We already have an alive queen."
+ user << "We already have a living royal!"
return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm
new file mode 100644
index 00000000000..ca664527d86
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm
@@ -0,0 +1,64 @@
+/mob/living/carbon/alien/humanoid/royal/praetorian
+ name = "alien praetorian"
+ caste = "p"
+ maxHealth = 250
+ health = 250
+ icon_state = "alienp"
+
+
+
+/mob/living/carbon/alien/humanoid/royal/praetorian/New()
+
+ real_name = name
+
+ internal_organs += new /obj/item/organ/internal/alien/plasmavessel/large
+ internal_organs += new /obj/item/organ/internal/alien/resinspinner
+ internal_organs += new /obj/item/organ/internal/alien/acid
+ internal_organs += new /obj/item/organ/internal/alien/neurotoxin
+ AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve())
+ ..()
+
+/mob/living/carbon/alien/humanoid/royal/praetorian/handle_hud_icons_health()
+ if (healths)
+ if(stat != DEAD)
+ switch(health)
+ if(250 to INFINITY)
+ healths.icon_state = "health0"
+ if(200 to 250)
+ healths.icon_state = "health1"
+ if(150 to 200)
+ healths.icon_state = "health2"
+ if(100 to 150)
+ healths.icon_state = "health3"
+ if(50 to 100)
+ healths.icon_state = "health4"
+ if(0 to 50)
+ healths.icon_state = "health5"
+ else
+ healths.icon_state = "health6"
+ else
+ healths.icon_state = "health7"
+
+
+/mob/living/carbon/alien/humanoid/royal/praetorian/movement_delay()
+ . = ..()
+ . += 1
+
+/obj/effect/proc_holder/alien/royal/praetorian/evolve
+ name = "Evolve"
+ desc = "Produce an interal egg sac capable of spawning children. Only one queen can exist at a time."
+ plasma_cost = 500
+
+ action_icon_state = "alien_evolve_praetorian"
+
+/obj/effect/proc_holder/alien/royal/praetorian/evolve/fire(mob/living/carbon/alien/user)
+ if(!alien_type_present(/mob/living/carbon/alien/humanoid/royal/queen))
+ user << "You begin to evolve!"
+ user.visible_message("[user] begins to twist and contort!")
+ var/mob/living/carbon/alien/humanoid/royal/queen/new_xeno = new (user.loc)
+ user.mind.transfer_to(new_xeno)
+ qdel(user)
+ return 1
+ else
+ user << "We already have an alive queen."
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/death.dm b/code/modules/mob/living/carbon/alien/humanoid/death.dm
index de4438814ef..9e2d3706d6c 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/death.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/death.dm
@@ -9,6 +9,7 @@
update_canmove()
if(client) blind.layer = 0
update_icons()
+ status_flags |=CANPUSH
tod = worldtime2text() //weasellos time of death patch
if(mind) mind.store_memory("Time of death: [tod]", 0)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index b5bbee5eb4c..f82f4ca38c0 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -32,10 +32,16 @@
if(user.a_intent == "harm")
..(user, 1)
adjustBruteLoss(14 + rand(1,9))
- Paralyse(1)
- step_away(src,user,15)
- sleep(1)
- step_away(src,user,15)
+ var/hitverb = "punched"
+ if(mob_size < MOB_SIZE_LARGE)
+ Paralyse(1)
+ step_away(src,user,15)
+ sleep(1)
+ step_away(src,user,15)
+ hitverb = "slammed"
+ playsound(loc, "punch", 25, 1, -1)
+ visible_message("[user] has [hitverb] [src]!", \
+ "[user] has [hitverb] [src]!")
return 1
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
@@ -140,4 +146,14 @@
return 1
/mob/living/carbon/alien/humanoid/get_permeability_protection()
- return 0.8
\ No newline at end of file
+ return 0.8
+
+//For alien evolution/promotion procs. Checks for
+proc/alien_type_present(var/alienpath)
+ for(var/mob/living/carbon/alien/humanoid/A in living_mob_list)
+ if(!istype(A, alienpath))
+ continue
+ if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid.
+ continue
+ return 1
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
index 540fc3874fd..d6b14d09b11 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
@@ -1,17 +1,27 @@
-/mob/living/carbon/alien/humanoid/queen
- name = "alien queen"
- caste = "q"
- maxHealth = 250
- health = 250
- icon_state = "alienq_s"
- status_flags = CANPARALYSE
+/mob/living/carbon/alien/humanoid/royal
+ //Common stuffs for Praetorian and Queen
+ icon = 'icons/mob/alienqueen.dmi'
+ status_flags = 0
ventcrawler = 0 //pull over that ass too fat
unique_name = 0
+ pixel_x = -16
+ mob_size = MOB_SIZE_LARGE
+ layer = 6
+ pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
+
+ var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
+
+/mob/living/carbon/alien/humanoid/royal/queen
+ name = "alien queen"
+ caste = "q"
+ maxHealth = 400
+ health = 400
+ icon_state = "alienq"
-/mob/living/carbon/alien/humanoid/queen/New()
+/mob/living/carbon/alien/humanoid/royal/queen/New()
//there should only be one queen
- for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list)
+ for(var/mob/living/carbon/alien/humanoid/royal/queen/Q in living_mob_list)
if(Q == src) continue
if(Q.stat == DEAD) continue
if(Q.client)
@@ -25,31 +35,31 @@
internal_organs += new /obj/item/organ/internal/alien/acid
internal_organs += new /obj/item/organ/internal/alien/neurotoxin
internal_organs += new /obj/item/organ/internal/alien/eggsac
-
+ AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
..()
-/mob/living/carbon/alien/humanoid/queen/handle_hud_icons_health()
+/mob/living/carbon/alien/humanoid/royal/queen/handle_hud_icons_health()
if (src.healths)
if (src.stat != 2)
switch(health)
- if(250 to INFINITY)
+ if(400 to INFINITY)
src.healths.icon_state = "health0"
- if(200 to 250)
+ if(320 to 400)
src.healths.icon_state = "health1"
- if(150 to 200)
+ if(240 to 320)
src.healths.icon_state = "health2"
- if(100 to 150)
+ if(160 to 240)
src.healths.icon_state = "health3"
- if(50 to 100)
+ if(80 to 160)
src.healths.icon_state = "health4"
- if(0 to 50)
+ if(0 to 80)
src.healths.icon_state = "health5"
else
src.healths.icon_state = "health6"
else
src.healths.icon_state = "health7"
-/mob/living/carbon/alien/humanoid/queen/movement_delay()
+/mob/living/carbon/alien/humanoid/royal/queen/movement_delay()
. = ..()
. += 5
@@ -70,8 +80,67 @@
new /obj/structure/alien/egg(user.loc)
return 1
-/mob/living/carbon/alien/humanoid/queen/large
- icon = 'icons/mob/alienqueen.dmi'
- icon_state = "queen_s"
- pixel_x = -16
- mob_size = MOB_SIZE_LARGE
+//Button to let queen choose her praetorian.
+/obj/effect/proc_holder/alien/royal/queen/promote
+ name = "Create Royal Parasite"
+ desc = "Produce a royal parasite to grant one of your children the honor of being your Praetorian."
+ plasma_cost = 450 //Plasma cost used on promotion, not spawning the parasite.
+
+ action_icon_state = "alien_queen_promote"
+
+
+
+/obj/effect/proc_holder/alien/royal/queen/promote/fire(mob/living/carbon/alien/user)
+ var/obj/item/queenpromote/prom
+ if(alien_type_present(/mob/living/carbon/alien/humanoid/royal/praetorian/))
+ user << "You already have a Praetorian!"
+ return 0
+ else
+ for(prom in user)
+ user << "You discard [prom]."
+ qdel(prom)
+ return 0
+
+ prom = new (user.loc)
+ if(!user.put_in_active_hand(prom, 1))
+ user << "You must empty your hands before preparing the parasite."
+ return 0
+ else //Just in case telling the player only once is not enough!
+ user << "Use the royal parasite on one of your children to promote her to Praetorian!"
+ return 0
+
+
+/obj/item/queenpromote
+ name = "\improper royal parasite"
+ desc = "Inject this into one of your grown children to promote her to a Praetorian!"
+ icon_state = "alien_medal"
+ flags = ABSTRACT|NODROP
+ icon = 'icons/mob/alien.dmi'
+
+/obj/item/queenpromote/attack(mob/living/M, mob/living/user)
+ if(!isalienadult(M) || istype(M, /mob/living/carbon/alien/humanoid/royal))
+ user << "You may only use this with your adult, non-royal children!"
+ return
+ if(alien_type_present(/mob/living/carbon/alien/humanoid/royal/praetorian/))
+ user << "You already have a Praetorian!"
+ return
+
+ var/mob/living/carbon/alien/humanoid/A = M
+ if(A.stat == CONSCIOUS && A.mind && A.key)
+ if(!A.usePlasma(450))
+ user << "You must have 450 plasma stored to use this!"
+ return
+
+ A << "The queen has granted you a promotion to Praetorian!"
+ user.visible_message("[A] begins to expand, twist and contort!")
+ var/mob/living/carbon/alien/humanoid/royal/praetorian/new_prae = new (A.loc)
+ A.mind.transfer_to(new_prae)
+ qdel(A)
+ qdel(src)
+ return
+ else
+ user << "This child must be alert and responsive to become a Praetorian!"
+
+/obj/item/queenpromote/attack_self(mob/user)
+ user << "You discard [src]."
+ qdel(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
index de272e0c0d7..dce532bbe14 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
@@ -21,6 +21,8 @@
icon_state = "alien[caste]_sleep"
else if(m_intent == "run")
icon_state = "alien[caste]_running"
+ else if(mob_size == MOB_SIZE_LARGE)
+ icon_state = "alien[caste]"
else
icon_state = "alien[caste]_s"
@@ -52,27 +54,29 @@
..()
update_icons()
-
-/mob/living/carbon/alien/humanoid/queen/large/update_icons()
- update_hud() //TODO: remove the need for this to be here
- overlays.Cut()
- if(stat == DEAD)
- icon_state = "queen_dead"
- else if((stat == UNCONSCIOUS && !sleeping) || weakened)
- icon_state = "queen_l"
- else if(sleeping || lying || resting)
- icon_state = "queen_sleep"
- else
- icon_state = "queen_s"
- for(var/image/I in overlays_standing)
- overlays += I
-
-/mob/living/carbon/alien/humanoid/queen/large/update_inv_l_hand()
- remove_overlay(L_HAND_LAYER)
- if(handcuffed)
- drop_l_hand()
-
-/mob/living/carbon/alien/humanoid/queen/large/update_inv_r_hand()
+//Royals have bigger sprites, so inhand things must be handled differently.
+/mob/living/carbon/alien/humanoid/royal/update_inv_r_hand()
+ ..()
remove_overlay(R_HAND_LAYER)
- if(handcuffed)
- drop_r_hand()
+ if(r_hand)
+ var/itm_state = r_hand.item_state
+ if(!itm_state)
+ itm_state = r_hand.icon_state
+
+ var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_r", "layer"=-R_HAND_LAYER)
+ overlays_standing[R_HAND_LAYER] = I
+
+ apply_overlay(R_HAND_LAYER)
+
+/mob/living/carbon/alien/humanoid/royal/update_inv_l_hand()
+ ..()
+ remove_overlay(L_HAND_LAYER)
+ if(l_hand)
+ var/itm_state = l_hand.item_state
+ if(!itm_state)
+ itm_state = l_hand.icon_state
+
+ var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_l", "layer"=-L_HAND_LAYER)
+ overlays_standing[L_HAND_LAYER] = I
+
+ apply_overlay(L_HAND_LAYER)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm
index 387c67ec242..5a1746e5ed2 100644
--- a/code/modules/mob/living/carbon/alien/say.dm
+++ b/code/modules/mob/living/carbon/alien/say.dm
@@ -14,7 +14,7 @@
if((!S.stat && S.hivecheck()) || (S in dead_mob_list))
S << rendered
-/mob/living/carbon/alien/humanoid/queen/alien_talk(message, shown_name = name)
+/mob/living/carbon/alien/humanoid/royal/queen/alien_talk(message, shown_name = name)
shown_name = "[shown_name]"
..(message, shown_name)
diff --git a/html/changelogs/Royal_Xenos_For_WJ.yml b/html/changelogs/Royal_Xenos_For_WJ.yml
new file mode 100644
index 00000000000..a8664c18050
--- /dev/null
+++ b/html/changelogs/Royal_Xenos_For_WJ.yml
@@ -0,0 +1,13 @@
+
+
+author: Gun Hog, for WJohnston
+
+
+delete-after: True
+
+
+changes:
+ - rscadd: "Add new Xenomorph caste: The Praetorian. Drones may become this on their way to growing into a full queen, and a queen may promote one if there is not one already."
+ - tweak: "Xenomorph queens are now GIGANTIC, along with the new Praetorian. Together, they are considered royals."
+ - tweak: "Queens are now significantly tougher to make up for their huge size."
+ - bugfix: "All forms of dead xenomorph may now be grabbed and placed on a surgery table for organ harvesting!"
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index c1ffea30969..5ce59d26edd 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi
index 24a4ca0cb63..b188463b657 100644
Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ
diff --git a/icons/mob/alienqueen.dmi b/icons/mob/alienqueen.dmi
index 72449bc2ea7..f002d2635ce 100644
Binary files a/icons/mob/alienqueen.dmi and b/icons/mob/alienqueen.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 846cf694b73..ad0ccecba7d 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1165,6 +1165,7 @@
#include "code\modules\mob\living\carbon\alien\humanoid\update_icons.dm"
#include "code\modules\mob\living\carbon\alien\humanoid\caste\drone.dm"
#include "code\modules\mob\living\carbon\alien\humanoid\caste\hunter.dm"
+#include "code\modules\mob\living\carbon\alien\humanoid\caste\praetorian.dm"
#include "code\modules\mob\living\carbon\alien\humanoid\caste\sentinel.dm"
#include "code\modules\mob\living\carbon\alien\larva\death.dm"
#include "code\modules\mob\living\carbon\alien\larva\emote.dm"