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"