diff --git a/code/datums/ghost_query.dm b/code/datums/ghost_query.dm index 47519813e8e..2f3f4884b5c 100644 --- a/code/datums/ghost_query.dm +++ b/code/datums/ghost_query.dm @@ -137,6 +137,14 @@ query_sound = 'sound/voice/hiss5.ogg' be_special_flag = BE_ALIEN +/datum/ghost_query/xenomorph_larva + role_name = "Xenomorph Larva" + question = "A xenomorph larva is ready to hatch from their egg. Would you like to join the hive?" + be_special_flag = BE_ALIEN + check_bans = list("Xenomorph") + cutoff_number = 1 + + /datum/ghost_query/blob role_name = "Blob" question = "A rapidly expanding Blob has just appeared on the facility. Would you like to play as it?" diff --git a/code/game/objects/structures/alien/alien egg.dm b/code/game/objects/structures/alien/alien egg.dm deleted file mode 100644 index eebdbb99691..00000000000 --- a/code/game/objects/structures/alien/alien egg.dm +++ /dev/null @@ -1,116 +0,0 @@ -#define MAX_PROGRESS 100 - -/obj/structure/alien/egg //Gurg Addition, working alien egg structure. - desc = "It looks like a weird egg." - name = "egg" - icon_state = "egg_growing" - density = FALSE - 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/dead/O in observer_mob_list) - if(O.client) - to_chat(O, "An alien is ready to hatch at [get_area(src.loc)]! (spawn)") - STOP_PROCESSING(SSobj, src) - update_icon() - -/obj/structure/alien/egg/update_icon() - if(progress == -1) - icon_state = "egg_opened" - else if(progress < MAX_PROGRESS) - icon_state = "egg_growing" - else - icon_state = "egg" - - // Ghostjoinable icon - var/static/image/I - if(!I) - I = image('icons/mob/hud_vr.dmi', "ghostjoin") - I.invisibility = INVISIBILITY_OBSERVER - I.plane = PLANE_GHOSTS - I.appearance_flags = KEEP_APART|RESET_TRANSFORM - - if(progress >= MAX_PROGRESS) - add_overlay(I) - else - cut_overlay(I) - - -/obj/structure/alien/egg/attack_ghost(var/mob/observer/dead/user) - // Still a ghost? - if(!istype(user)) - tgui_alert_async(user, "You have to be an observer to join as this Xenomorph larva.") - return - - // Check for bans properly. - if(jobban_isbanned(user, "Xenomorph")) - tgui_alert_async(user, "You are banned from playing a Xenomorph, so you can't join as this Xenomorph larva.") - return - - // Check for respawn - if(!user.MayRespawn(1)) - tgui_alert_async(user, "You aren't allowed to respawn, so you can't join as this Xenomorph larva.") - return - - if(progress == -1) - tgui_alert_async(user, "That egg has already hatched.") - else if(progress >= MAX_PROGRESS) - tgui_alert_async(user, "Are you sure you want to join as a Xenomorph larva?", "Become Larva", list("Yes","No"), CALLBACK(src, .proc/ghost_dunk), 20 SECONDS) - else - tgui_alert_async(user, "\The [src] has not yet matured.") - -/obj/structure/alien/egg/proc/ghost_dunk(choice) - if(choice != "Yes") - return - var/mob/observer/dead/user = usr - if(progress < MAX_PROGRESS || !istype(user)) - return - - progress = -1 // No harvesting pls. - flick("egg_opening",src) - sleep(5) //5ds animation - - if(!src || !istype(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)) - - // Move the ghost in - if(user.mind) - user.mind.active = TRUE - user.mind.transfer_to(larva) - else - larva.ckey = user.ckey - qdel(user) - - 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/structures/alien/alien.dm b/code/game/objects/structures/alien/alien.dm index 77945491f7c..0979677fdea 100644 --- a/code/game/objects/structures/alien/alien.dm +++ b/code/game/objects/structures/alien/alien.dm @@ -1,4 +1,4 @@ -/obj/structure/alien //Gurg Addition, framework for alien eggs and structures. +/obj/structure/alien //Gurg Addition, framework for alien structures. name = "alien thing" desc = "There's something alien about this." icon = 'icons/mob/alien.dmi' diff --git a/code/game/objects/structures/ghost_pods/antagonist.dm b/code/game/objects/structures/ghost_pods/antagonist.dm new file mode 100644 index 00000000000..96f68e4af7e --- /dev/null +++ b/code/game/objects/structures/ghost_pods/antagonist.dm @@ -0,0 +1,55 @@ +//Antagonist ghost pods for potentially self replicating creatures, xenomorphs as one example. These should not naturally spawn on their own. + +/obj/structure/ghost_pod/automatic/xenomorph_egg + name = "xenomorph egg" + desc = "A disgusting egg dripping with clear ooze, the existence of this is a omen for what is to come." + description_info = "This contains a growing xenomorph larva, which may wake up at any moment. The larva will be another player, once activated." + icon = 'icons/mob/alien.dmi' + icon_state = "egg" + icon_state_opened = "egg_opened" //Can be placed on map with used = 1 for POI decorations + var/health = 50 //So they can be destroyed by the crew + density = FALSE + ghost_query_type = /datum/ghost_query/xenomorph_larva + delay_to_try_again = 1 MINUTES //10 minutes for egg to grow, 5 minutes for larva to mature + +/obj/structure/ghost_pod/automatic/xenomorph_egg/create_occupant(var/mob/M) + var/mob/living/carbon/alien/larva/R = new(get_turf(src)) + if(M.mind) + M.mind.transfer_to(R) + // Description for new larva, so they understand what to expect. + to_chat(M, "You are a Xenomorph Larva, freshly slithered out of their egg to serve the hive.") + to_chat(M, "Be sure to carefully listen to your queen, as xenomorph egg spawns may act different to loner xenomorph spawns.") + to_chat(M, "Remember, you are technically a antagonist. Be sure to learn the context of your existence via IC or ahelp to prevent headaches, and follow the orders of your queen to the letter.") + to_chat(M, " Your life for the hive!") + R.ckey = M.ckey + visible_message("\the [src] peels open, and a fresh larva slithers out!") + ..() + +/obj/structure/ghost_pod/automatic/xenomorph_egg/proc/healthcheck() + if(health <=0) + visible_message("\the [src] splatters everywhere as it cracks open!") + playsound(src, 'sound/effects/slime_squish.ogg', 50, 1) + qdel(src) + return + +/obj/structure/ghost_pod/automatic/xenomorph_egg/attackby(obj/item/W as obj, mob/user as mob) + user.setClickCooldown(user.get_attack_speed(W)) + switch(W.damtype) + if("fire") + health -= W.force * 1.25 //It really doesn't like fire + if("brute") + health -= W.force * 0.75 //Bit hard to cut + playsound(src, 'sound/effects/attackblob.ogg', 50, 1) + healthcheck() + ..() + return + +/obj/structure/ghost_pod/automatic/xenomorph_egg/bullet_act(var/obj/item/projectile/Proj) + switch(damtype) + if("fire") + health -= Proj.damage * 1.5 //It burns! + if("brute") + health -= Proj.damage //It hurts a bit more then a sharp stick + healthcheck() + ..() + return 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 f627a191fec..6015dd16a9b 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 @@ -79,8 +79,8 @@ // Queen verbs. /mob/living/carbon/human/proc/lay_egg() - set name = "Lay Egg (200)" - set desc = "Lay an egg to produce huggers to impregnate prey with." + set name = "Lay Egg (500)" //Cost is entire queen reserve, to compensate being able to reproduce on it's own + set desc = "Lay an egg that will eventually hatch into a new xenomorph larva. Life finds a way." set category = "Abilities" if(!config.aliens_allowed) @@ -88,13 +88,13 @@ verbs -= /mob/living/carbon/human/proc/lay_egg return - if(locate(/obj/structure/alien/egg) in get_turf(src)) + if(locate(/obj/structure/ghost_pod/automatic/xenomorph_egg) in get_turf(src)) to_chat(src, "There's already an egg here.") return - if(check_alien_ability(200,1,O_EGG)) + if(check_alien_ability(500,1,O_EGG)) visible_message("[src] has laid an egg!") - new /obj/structure/alien/egg(loc) + new /obj/structure/ghost_pod/automatic/xenomorph_egg(loc) return @@ -243,7 +243,7 @@ if(iswall(targetLoc)) targetLoc = get_turf(src) - + var/obj/O switch(choice) diff --git a/vorestation.dme b/vorestation.dme index fd67cf0453f..e24413049cb 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -1526,7 +1526,6 @@ #include "code\game\objects\structures\window.dm" #include "code\game\objects\structures\window_spawner.dm" #include "code\game\objects\structures\window_vr.dm" -#include "code\game\objects\structures\alien\alien egg.dm" #include "code\game\objects\structures\alien\alien.dm" #include "code\game\objects\structures\alien\resin structures.dm" #include "code\game\objects\structures\crates_lockers\__closets.dm" @@ -1572,6 +1571,7 @@ #include "code\game\objects\structures\flora\grass.dm" #include "code\game\objects\structures\flora\moretrees_vr.dm" #include "code\game\objects\structures\flora\trees.dm" +#include "code\game\objects\structures\ghost_pods\antagonist.dm" #include "code\game\objects\structures\ghost_pods\event_vr.dm" #include "code\game\objects\structures\ghost_pods\ghost_pods.dm" #include "code\game\objects\structures\ghost_pods\ghost_pods_vr.dm"