From de3b9a04ee517eec6df8550d272e3cfacea01ecf Mon Sep 17 00:00:00 2001 From: zxaber <37497534+zxaber@users.noreply.github.com> Date: Mon, 2 Mar 2020 16:25:33 -0800 Subject: [PATCH] Ash Walker flavor text, balance changes (#49316) * Ashen One May the flames guide thee * Update code/game/objects/structures/ghost_role_spawners.dm Co-Authored-By: XDTM * update * caught it before I got yelled at * updates * Update code/game/objects/structures/ghost_role_spawners.dm Co-Authored-By: moo <11748095+ExcessiveUseOfCobblestone@users.noreply.github.com> * Update code/game/objects/structures/ghost_role_spawners.dm Co-Authored-By: moo <11748095+ExcessiveUseOfCobblestone@users.noreply.github.com> * spaced the spaces tab good space bad Co-authored-by: XDTM Co-authored-by: moo <11748095+ExcessiveUseOfCobblestone@users.noreply.github.com> --- code/__DEFINES/traits.dm | 1 + code/_globalvars/traits.dm | 1 + code/game/mecha/mecha.dm | 3 + .../objects/structures/ghost_role_spawners.dm | 56 ++++++++++++++++++- .../antagonists/ashwalker/ashwalker.dm | 1 + code/modules/awaymissions/corpse.dm | 6 ++ .../ruins/objects_and_mobs/ash_walker_den.dm | 40 ++++++++++++- 7 files changed, 104 insertions(+), 4 deletions(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 269d41365b8..f8d672f9bbe 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -157,6 +157,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NOFLASH "noflash" //Makes you immune to flashes #define TRAIT_XENO_IMMUNE "xeno_immune"//prevents xeno huggies implanting skeletons #define TRAIT_NAIVE "naive" +#define TRAIT_PRIMITIVE "primitive" #define TRAIT_GUNFLIP "gunflip" //non-mob traits diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 1fbfb67d821..1b38a810f7b 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -98,6 +98,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NOFLASH" = TRAIT_NOFLASH, "TRAIT_XENO_IMMUNE" = TRAIT_XENO_IMMUNE, "TRAIT_NAIVE" = TRAIT_NAIVE, + "TRAIT_PRIMITIVE" = TRAIT_PRIMITIVE, //unable to use mechs. Given to Ash Walkers "TRAIT_GUNFLIP" = TRAIT_GUNFLIP ), /obj/item/bodypart = list( diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 599fdf00b03..3d845303bfb 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -878,6 +878,9 @@ return if(!ishuman(user)) // no silicons or drones in mechas. return + if(HAS_TRAIT(user, TRAIT_PRIMITIVE)) //no lavalizards either. + to_chat(user, "The knowledge to use this device eludes you!") + return log_message("[user] tries to move in.", LOG_MECHA) if (occupant) to_chat(usr, "The [name] is already occupied!") diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 21c3edab42c..9648fa0c214 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -33,6 +33,45 @@ //Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers. +/obj/structure/ash_walker_eggshell + name = "ash walker egg" + desc = "A man-sized yellow egg, spawned from some unfathomable creature. A humanoid silhouette lurks within. The egg shell looks resistant to temperature but otherwise rather brittle." + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' + icon_state = "large_egg" + resistance_flags = LAVA_PROOF | FIRE_PROOF | FREEZE_PROOF + max_integrity = 80 + var/obj/effect/mob_spawn/human/ash_walker/egg + +/obj/structure/ash_walker_eggshell/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) //lifted from xeno eggs + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(loc, 'sound/effects/attackblob.ogg', 100, TRUE) + else + playsound(src, 'sound/weapons/tap.ogg', 50, TRUE) + if(BURN) + if(damage_amount) + playsound(loc, 'sound/items/welder.ogg', 100, TRUE) + +/obj/structure/ash_walker_eggshell/attack_ghost(mob/user) //Pass on ghost clicks to the mob spawner + if(egg) + egg.attack_ghost(user) + . = ..() + +/obj/structure/ash_walker_eggshell/Destroy() + if(!egg) + return ..() + var/mob/living/carbon/human/yolk = new /mob/living/carbon/human/(get_turf(src)) + yolk.fully_replace_character_name(null,random_unique_lizard_name(gender)) + yolk.set_species(/datum/species/lizard/ashwalker) + yolk.underwear = "Nude" + yolk.equipOutfit(/datum/outfit/ashwalker)//this is an authentic mess we're making + yolk.update_body() + yolk.gib() + qdel(egg) + return ..() + + /obj/effect/mob_spawn/human/ash_walker name = "ash walker egg" desc = "A man-sized yellow egg, spawned from some unfathomable creature. A humanoid silhouette lurks within." @@ -43,7 +82,6 @@ outfit = /datum/outfit/ashwalker roundstart = FALSE death = FALSE - anchored = FALSE move_resist = MOVE_FORCE_NORMAL density = FALSE short_desc = "You are an ash walker. Your tribe worships the Necropolis." @@ -52,10 +90,17 @@ Fresh sacrifices for your nest." assignedrole = "Ash Walker" var/datum/team/ashwalkers/team + var/obj/structure/ash_walker_eggshell/eggshell + +/obj/effect/mob_spawn/human/ash_walker/allow_spawn(mob/user) + if(!(user.key in team.players_spawned))//one per person unless you get a bonus spawn + return TRUE + to_chat(user, "You have exhausted your usefulness to the Necropolis.") + return FALSE /obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn) new_spawn.fully_replace_character_name(null,random_unique_lizard_name(gender)) - to_chat(new_spawn, "Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Don't leave your nest undefended, protect it with your life. Glory to the Necropolis!") + to_chat(new_spawn, "Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Invade the strange structure of the outsiders if you must. Do not cause unnecessary destruction, as littering the wastes with ugly wreckage is certain to not gain you favor. Glory to the Necropolis!") new_spawn.mind.add_antag_datum(/datum/antagonist/ashwalker, team) @@ -63,11 +108,18 @@ var/mob/living/carbon/human/H = new_spawn H.underwear = "Nude" H.update_body() + ADD_TRAIT(H, TRAIT_PRIMITIVE, ROUNDSTART_TRAIT) + team.players_spawned += (new_spawn.key) + eggshell.egg = null + qdel(eggshell) /obj/effect/mob_spawn/human/ash_walker/Initialize(mapload, datum/team/ashwalkers/ashteam) . = ..() var/area/A = get_area(src) team = ashteam + eggshell = new /obj/structure/ash_walker_eggshell(get_turf(loc)) + eggshell.egg = src + src.forceMove(eggshell) if(A) notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_ASHWALKER) diff --git a/code/modules/antagonists/ashwalker/ashwalker.dm b/code/modules/antagonists/ashwalker/ashwalker.dm index 5e2abc9fd08..4246ca05837 100644 --- a/code/modules/antagonists/ashwalker/ashwalker.dm +++ b/code/modules/antagonists/ashwalker/ashwalker.dm @@ -1,6 +1,7 @@ /datum/team/ashwalkers name = "Ashwalkers" show_roundend_report = FALSE + var/list/players_spawned = new /datum/antagonist/ashwalker name = "Ash Walker" diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 50fd857b58b..0cb1b9e5431 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -41,9 +41,12 @@ if(is_banned_from(user.key, banType)) to_chat(user, "You are jobanned!") return + if(!allow_spawn(user)) + return if(QDELETED(src) || QDELETED(user)) return var/ghost_role = alert("Become [mob_name]? (Warning, You can no longer be revived!)",,"Yes","No") + if(ghost_role == "No" || !loc) return log_game("[key_name(user)] became [mob_name]") @@ -65,6 +68,9 @@ GLOB.mob_spawners -= name return ..() +/obj/effect/mob_spawn/proc/allow_spawn(mob/user) //Override this to add spawn limits to a ghost role + return TRUE + /obj/effect/mob_spawn/proc/special(mob/M) return diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm index dc2900297c5..6e76b8f9a9b 100644 --- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm @@ -38,15 +38,40 @@ /obj/structure/lavaland/ash_walker/proc/consume() for(var/mob/living/H in view(src, 1)) //Only for corpse right next to/on same tile if(H.stat) - visible_message("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.") - playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, TRUE) for(var/obj/item/W in H) if(!H.dropItemToGround(W)) qdel(W) + if(issilicon(H)) //no advantage to sacrificing borgs... + H.gib() + visible_message("Serrated tendrils eagerly pull [H] apart, but find nothing of interest.") + return + + if(H.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (H.key || H.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached + visible_message("Serrated tendrils carefully pull [H] to [src], absorbing the body and creating it anew.") + var/datum/mind/deadmind + if(H.key) + deadmind = H + else + deadmind = H.get_ghost(FALSE, TRUE) + to_chat(deadmind, "Your body has been returned to the nest. You are being remade anew, and will awaken shortly.
Your memories will remain intact in your new body, as your soul is being salvaged") + SEND_SOUND(deadmind, sound('sound/magic/enter_blood.ogg',volume=100)) + addtimer(CALLBACK(src, .proc/remake_walker, H.mind, H.real_name), 20 SECONDS) + new /obj/effect/gibspawner/generic(get_turf(H)) + qdel(H) + return + if(ismegafauna(H)) meat_counter += 20 else meat_counter++ + visible_message("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.") + playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, TRUE) + var/deliverykey = H.fingerprintslast //key of whoever brought the body + var/mob/living/deliverymob = get_mob_by_key(deliverykey) //mob of said key + //there is a 40% chance that the Lava Lizard unlocks their respawn with each sacrifice + if(deliverymob && (deliverymob.mind?.has_antag_datum(/datum/antagonist/ashwalker)) && (deliverykey in ashies.players_spawned) && (prob(40))) + to_chat(deliverymob, "The Necropolis is pleased with your sacrifice. You feel confident your existence after death is secure.") + ashies.players_spawned -= deliverykey H.gib() obj_integrity = min(obj_integrity + max_integrity*0.05,max_integrity)//restores 5% hp of tendril for(var/mob/living/L in view(src, 5)) @@ -55,6 +80,17 @@ else SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "oogabooga", /datum/mood_event/sacrifice_bad) +/obj/structure/lavaland/ash_walker/proc/remake_walker(var/datum/mind/oldmind, var/oldname) + var/mob/living/carbon/human/M = new /mob/living/carbon/human(get_step(loc, pick(GLOB.alldirs))) + M.set_species(/datum/species/lizard/ashwalker) + M.real_name = oldname + M.underwear = "Nude" + M.update_body() + oldmind.transfer_to(M) + M.mind.grab_ghost() + to_chat(M, "You have been pulled back from beyond the grave, with a new body and renewed purpose. Glory to the Necropolis!") + playsound(get_turf(M),'sound/magic/exit_blood.ogg', 100, TRUE) + /obj/structure/lavaland/ash_walker/proc/spawn_mob() if(meat_counter >= ASH_WALKER_SPAWN_THRESHOLD) new /obj/effect/mob_spawn/human/ash_walker(get_step(loc, pick(GLOB.alldirs)), ashies)