diff --git a/code/modules/antagonists/ashwalker/ashwalker.dm b/code/modules/antagonists/ashwalker/ashwalker.dm index 6d377dbe39f..f59a1e4096e 100644 --- a/code/modules/antagonists/ashwalker/ashwalker.dm +++ b/code/modules/antagonists/ashwalker/ashwalker.dm @@ -12,16 +12,6 @@ suicide_cry = "I HAVE NO IDEA WHAT THIS THING DOES!!" count_against_dynamic_roll_chance = FALSE var/datum/team/ashwalkers/ashie_team - //SKYRAT EDIT: Recipes for Tribals - ///The list of recipes that will be learned on inheriting the antag datum - var/static/list/antag_recipes = list( - /datum/crafting_recipe/bonesword, - /datum/crafting_recipe/ash_recipe/macahuitl, - /datum/crafting_recipe/boneaxe, - /datum/crafting_recipe/bonespear, - /datum/crafting_recipe/bonedagger, - ) - //SKYRAT EDIT: Recipes for Tribals /datum/antagonist/ashwalker/create_team(datum/team/team) if(team) @@ -41,10 +31,6 @@ /datum/antagonist/ashwalker/on_gain() . = ..() RegisterSignal(owner.current, COMSIG_MOB_EXAMINATE, .proc/on_examinate) - //SKYRAT EDIT: Recipes for Tribals - for(var/recipe_datum in antag_recipes) - owner.teach_crafting_recipe(recipe_datum) - //SKYRAT EDIT: Recipes for Tribals /datum/antagonist/ashwalker/on_removal() . = ..() diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm index 9fc1a88c295..89004709be0 100644 --- a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm @@ -33,16 +33,6 @@ ashies = null QDEL_NULL(linked_objective) STOP_PROCESSING(SSprocessing, src) - //SKYRAT EDIT START - var/compiled_string = "The [src] has been destroyed at [loc_name(src.loc)], nearest mobs are " - var/found_anyone = FALSE - for(var/mob/living/carbon/carbons_nearby in range(7)) - compiled_string += "[key_name(carbons_nearby)]," - found_anyone = TRUE - if(!found_anyone) - compiled_string += "nobody." - log_game(compiled_string) - //SKYRAT EDIT END return ..() /obj/structure/lavaland/ash_walker/deconstruct(disassembled) @@ -55,6 +45,7 @@ consume() spawn_mob() +//PLEASE VIEW SKYRAT ASHWALKER MODULE FOR OVERRIDE /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) @@ -100,33 +91,18 @@ else L.add_mood_event("oogabooga", /datum/mood_event/sacrifice_bad) -/obj/structure/lavaland/ash_walker/proc/remake_walker(datum/mind/oldmind, oldname) // SKYRAT EDIT BEGIN - Ashwalker Respawning Fix - var/mob/living/carbon/human/my_ashie - var/ask = tgui_alert(oldmind, "You have been returned to the nest. \nDo you wish to be a random Ash Walker or your loaded Ash-Walker?", "Returned to Nest", list("Loaded Character", "Random Ash-Walker")) - switch(ask) - if("Random Ash-Walker") - my_ashie = new /mob/living/carbon/human(get_step(loc, pick(GLOB.alldirs))) - my_ashie.set_species(/datum/species/lizard/ashwalker) - my_ashie.real_name = oldname - my_ashie.underwear = "Nude" - my_ashie.update_body() - my_ashie.remove_language(/datum/language/common) - oldmind.transfer_to(my_ashie) - my_ashie.mind.grab_ghost() - to_chat(my_ashie, "You have been pulled back from beyond the grave, with a new body and renewed purpose. Glory to the Necropolis!") - playsound(get_turf(my_ashie),'sound/magic/exit_blood.ogg', 100, TRUE) - if("Loaded Character") - my_ashie = new /mob/living/carbon/human(get_step(loc, pick(GLOB.alldirs))) - oldmind.transfer_to(my_ashie) // oh no - my_ashie?.client?.prefs?.safe_transfer_prefs_to(my_ashie) - my_ashie.dna.update_dna_identity() - if(!my_ashie.dna.species.id == SPECIES_LIZARD_ASH) - QDEL_NULL(my_ashie) - to_chat(oldmind, "Load an Ash-Walker to this slot!") // whew - return - to_chat(my_ashie, "You have been pulled back from beyond the grave, with a new body and renewed purpose. Glory to the Necropolis!") - playsound(get_turf(my_ashie),'sound/magic/exit_blood.ogg', 100, TRUE) // SKYRAT EDIT END - Ashwalker Respawning Fix - +//PLEASE VIEW SKYRAT ASHWALKER MODULE FOR REPLACEMENT +/obj/structure/lavaland/ash_walker/proc/remake_walker(datum/mind/oldmind, 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() + M.remove_language(/datum/language/common) + 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) diff --git a/modular_skyrat/master_files/code/datums/components/crafting.dm b/modular_skyrat/master_files/code/datums/components/crafting.dm new file mode 100644 index 00000000000..f8abb762820 --- /dev/null +++ b/modular_skyrat/master_files/code/datums/components/crafting.dm @@ -0,0 +1,9 @@ +/** + * The opposite of proc/teach_crafting_recipe + * will attempt to remove the arg "recipe" from the learned recipes + */ +/datum/mind/proc/unteach_crafting_recipe(recipe) + if(!learned_recipes) + return + + learned_recipes &= ~recipe diff --git a/modular_skyrat/master_files/code/modules/antagonists/_common/antag_datum.dm b/modular_skyrat/master_files/code/modules/antagonists/_common/antag_datum.dm index 9005218c859..3965cc6b866 100644 --- a/modular_skyrat/master_files/code/modules/antagonists/_common/antag_datum.dm +++ b/modular_skyrat/master_files/code/modules/antagonists/_common/antag_datum.dm @@ -1,6 +1,27 @@ /datum/antagonist /// Should this antagonist be allowed to view exploitable information? var/view_exploitables = FALSE + /// the list of recipes that an antag will learn/unlearn on gain/loss + var/list/antag_recipes = list() + +/datum/antagonist/on_gain() + . = ..() + for(var/recipe_datum in antag_recipes) + owner.teach_crafting_recipe(recipe_datum) + +/datum/antagonist/on_removal() + . = ..() + for(var/recipe_datum in antag_recipes) + owner.unteach_crafting_recipe(recipe_datum) + +/datum/antagonist/ashwalker + antag_recipes = list( + /datum/crafting_recipe/bonesword, + /datum/crafting_recipe/ash_recipe/macahuitl, + /datum/crafting_recipe/boneaxe, + /datum/crafting_recipe/bonespear, + /datum/crafting_recipe/bonedagger, + ) /datum/antagonist/heretic view_exploitables = TRUE @@ -43,3 +64,4 @@ /*/datum/antagonist/abductor // maybe? view_exploitables = TRUE */ + diff --git a/modular_skyrat/modules/ashwalkers/code/buildings/ash_tendril.dm b/modular_skyrat/modules/ashwalkers/code/buildings/ash_tendril.dm new file mode 100644 index 00000000000..c9756a1ad44 --- /dev/null +++ b/modular_skyrat/modules/ashwalkers/code/buildings/ash_tendril.dm @@ -0,0 +1,165 @@ +#define REQUIRED_OBSERVERS 2 +#define MEGAFAUNA_MEAT_AMOUNT 20 + +//this is for revitalizing/preserving regen cores +/obj/structure/lavaland/ash_walker/attackby(obj/item/attacking_item, mob/living/user, params) + if(!istype(attacking_item, /obj/item/organ/internal/regenerative_core)) + return ..() + + if(!user.mind.has_antag_datum(/datum/antagonist/ashwalker)) + balloon_alert(user, "must be an ashwalker!") + return + + var/obj/item/organ/internal/regenerative_core/regen_core = attacking_item + regen_core.preserved() + playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) + balloon_alert_to_viewers("[src] revitalizes [regen_core]!") + return + +//this is for logging the destruction of the tendril +/obj/structure/lavaland/ash_walker/Destroy() + var/compiled_string = "The [src] has been destroyed at [loc_name(src.loc)], nearest mobs are " + var/found_anyone = FALSE + + for(var/mob/living/carbon/carbons_nearby in range(7)) + compiled_string += "[key_name(carbons_nearby)]," + found_anyone = TRUE + + if(!found_anyone) + compiled_string += "nobody." + + log_game(compiled_string) + return ..() + +//this is for transforming a person into an ashwalker +/obj/structure/lavaland/ash_walker/attack_hand(mob/living/user, list/modifiers) + if(!ishuman(user)) + return + + var/mob/living/carbon/human/human_user = user + if(istype(human_user.dna.species, /datum/species/lizard/ashwalker)) + return + + var/allow_transform = 0 + + for(var/mob/living/carbon/human/count_human in range(2, src)) + if(!istype(count_human.dna.species, /datum/species/lizard/ashwalker)) + continue + + allow_transform++ + + if(allow_transform < REQUIRED_OBSERVERS) + balloon_alert_to_viewers("[src] rejects the request, not enough viewers!") + playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) + human_user.adjustBruteLoss(10) + return + + else + balloon_alert_to_viewers("[src] reaches out to [human_user]...") + var/choice = tgui_alert(human_user, "Become an Ashwalker? You will abandon your previous life and body.", "Major Choice", list("Yes", "No")) + + if(choice != "Yes") + balloon_alert_to_viewers("[src] feels rejected and punishes [human_user]!") + playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) + human_user.adjustBruteLoss(50) + return + + balloon_alert_to_viewers("[src] rejoices and transforms [human_user]!") + human_user.unequip_everything() + human_user.set_species(/datum/species/lizard/ashwalker) + human_user.underwear = "Nude" + human_user.update_body() + human_user.mind.add_antag_datum(/datum/antagonist/ashwalker) + + if(SSmapping.level_trait(human_user.z, ZTRAIT_ICE_RUINS) || SSmapping.level_trait(human_user.z, ZTRAIT_ICE_RUINS_UNDERGROUND)) + ADD_TRAIT(human_user, TRAIT_NOBREATH, ROUNDSTART_TRAIT) + ADD_TRAIT(human_user, TRAIT_RESISTCOLD, ROUNDSTART_TRAIT) + + ADD_TRAIT(human_user, TRAIT_PRIMITIVE, ROUNDSTART_TRAIT) + playsound(src, 'sound/magic/demon_dies.ogg', 50, TRUE) + meat_counter++ + + return ..() + +//this is the skyrat override +/obj/structure/lavaland/ash_walker/consume() + for(var/mob/living/viewable_living in view(src, 1)) //Only for corpse right next to/on same tile + if(!viewable_living.stat) + continue + + for(var/obj/item/sacrifice_posession in viewable_living) + if(!viewable_living.dropItemToGround(sacrifice_posession)) + qdel(sacrifice_posession) + + if(issilicon(viewable_living)) //no advantage to sacrificing borgs... + viewable_living.gib() + continue + + if(viewable_living.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (viewable_living.key || viewable_living.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached + revive_ashwalker(viewable_living) + continue + + if(ismegafauna(viewable_living)) + meat_counter += MEGAFAUNA_MEAT_AMOUNT + + else + meat_counter++ + + playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, TRUE) + var/delivery_key = viewable_living.fingerprintslast //key of whoever brought the body + var/mob/living/delivery_mob = get_mob_by_key(delivery_key) //mob of said key + + //there is a 40% chance that the Lava Lizard unlocks their respawn with each sacrifice + if(delivery_mob && (delivery_mob.mind?.has_antag_datum(/datum/antagonist/ashwalker)) && (delivery_key in ashies.players_spawned) && prob(40)) + to_chat(delivery_mob, span_boldwarning("The Necropolis is pleased with your sacrifice. You feel confident your existence after death is secure.")) + ashies.players_spawned -= delivery_key + + viewable_living.gib() + atom_integrity = min(atom_integrity + max_integrity * 0.05, max_integrity) //restores 5% hp of tendril + + for(var/mob/living/living_observers in view(src, 5)) + if(living_observers.mind?.has_antag_datum(/datum/antagonist/ashwalker)) + living_observers.add_mood_event("oogabooga", /datum/mood_event/sacrifice_good) + + else + living_observers.add_mood_event("oogabooga", /datum/mood_event/sacrifice_bad) + +/** + * Proc that will spawn the egg that will revive the ashwalker + * This is also the Skyrat replacement for /proc/remake_walker + */ +/obj/structure/lavaland/ash_walker/proc/revive_ashwalker(mob/living/carbon/human/revived_ashwalker) + var/obj/structure/reviving_ashwalker_egg/spawned_egg = new(get_step(loc, pick(GLOB.alldirs))) + revived_ashwalker.forceMove(spawned_egg) + to_chat(revived_ashwalker, span_warning("The tendril has decided to be merciful and revive you within a minute, have patience.")) + +/obj/structure/reviving_ashwalker_egg + name = "occupied ashwalker egg" + desc = "Past the typical appearance of the yellow, man-sized egg, there seems to be a body floating within!" + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "large_egg" + resistance_flags = LAVA_PROOF | FIRE_PROOF | FREEZE_PROOF + max_integrity = 80 + +/obj/structure/reviving_ashwalker_egg/Initialize(mapload) + . = ..() + addtimer(CALLBACK(src, .proc/do_revive), 30 SECONDS) + +/** + * Proc that will fully revive the living content inside and then destroy itself + */ +/obj/structure/reviving_ashwalker_egg/proc/do_revive() + var/mob/living/living_inside = locate() in contents + + if(!living_inside) + qdel(src) + return + + living_inside.revive(full_heal = TRUE, admin_revive = TRUE) + living_inside.forceMove(get_turf(src)) + living_inside.mind.grab_ghost() + living_inside.balloon_alert_to_viewers("[living_inside] breaks out of [src]!") + qdel(src) + +#undef REQUIRED_OBSERVERS +#undef MEGAFAUNA_MEAT_AMOUNT diff --git a/modular_skyrat/modules/ashwalkers/code/buildings/tendril_corruption.dm b/modular_skyrat/modules/ashwalkers/code/buildings/tendril_corruption.dm deleted file mode 100644 index c825b9f8a7a..00000000000 --- a/modular_skyrat/modules/ashwalkers/code/buildings/tendril_corruption.dm +++ /dev/null @@ -1,57 +0,0 @@ -/obj/item/flashlight/lantern/ashwalker_variant - name = "ash-corrupted lantern" - uses_battery = FALSE - light_range = 8 - -/obj/structure/lavaland/ash_walker/attackby(obj/item/I, mob/living/user, params) - if(istype(I, /obj/item/organ/internal/regenerative_core) && user.mind.has_antag_datum(/datum/antagonist/ashwalker)) - var/obj/item/organ/internal/regenerative_core/regen_core = I - regen_core.preserved() - playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) - to_chat(user, span_notice("The tendril revitalizes [regen_core].")) - return - if(istype(I, /obj/item/flashlight/lantern)) - var/obj/item/flashlight/lantern/corrupted_lanter = I - new /obj/item/flashlight/lantern/ashwalker_variant(get_turf(user)) - playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) - to_chat(user, span_notice("The tendril corrupts [corrupted_lanter].")) - qdel(corrupted_lanter) - return - return ..() - -/obj/structure/lavaland/ash_walker/attack_hand(mob/living/user, list/modifiers) - if(!ishuman(user)) - return - var/mob/living/carbon/human/human_user = user - if(istype(human_user.dna.species, /datum/species/lizard/ashwalker)) - return - var/allow_transform = 0 - for(var/mob/living/carbon/human/count_human in range(1, src)) - if(istype(count_human.dna.species, /datum/species/lizard/ashwalker)) - allow_transform++ - if(allow_transform < 2) - to_chat(human_user, span_warning("The tendril consumes a part of your flesh... you are not worthy!")) - playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) - human_user.adjustBruteLoss(10) - return - else - to_chat(human_user, span_warning("The tendril consumes a part of your flesh... you have a chance!")) - var/choice = tgui_alert(human_user, "Become an Ashwalker? You will abandon your previous life and body.", "Major Choice", list("Yes", "No")) - if(choice != "Yes") - to_chat(human_user, span_warning("You will live long enough to regret this...")) - playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) - human_user.adjustBruteLoss(10) - return - to_chat(human_user, span_notice("The tendril is pleased with your choice...")) - human_user.unequip_everything() - human_user.set_species(/datum/species/lizard/ashwalker) - human_user.underwear = "Nude" - human_user.update_body() - human_user.mind.add_antag_datum(/datum/antagonist/ashwalker) - if(SSmapping.level_trait(human_user.z, ZTRAIT_ICE_RUINS_UNDERGROUND) || SSmapping.level_trait(human_user.z, ZTRAIT_ICE_RUINS_UNDERGROUND)) - ADD_TRAIT(human_user, TRAIT_NOBREATH, ROUNDSTART_TRAIT) - ADD_TRAIT(human_user, TRAIT_RESISTCOLD, ROUNDSTART_TRAIT) - ADD_TRAIT(human_user, TRAIT_PRIMITIVE, ROUNDSTART_TRAIT) - playsound(src, 'sound/magic/demon_dies.ogg', 50, TRUE) - meat_counter++ - return ..() diff --git a/tgstation.dme b/tgstation.dme index bea7c91531b..8968924389c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4888,6 +4888,7 @@ #include "modular_skyrat\master_files\code\datums\emotes.dm" #include "modular_skyrat\master_files\code\datums\ert.dm" #include "modular_skyrat\master_files\code\datums\outfits.dm" +#include "modular_skyrat\master_files\code\datums\components\crafting.dm" #include "modular_skyrat\master_files\code\datums\components\fullauto.dm" #include "modular_skyrat\master_files\code\datums\components\shielded_suit.dm" #include "modular_skyrat\master_files\code\datums\components\tippable.dm" @@ -5166,9 +5167,9 @@ #include "modular_skyrat\modules\armaments\code\armament_station.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\ash_clothing_vendor.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\ash_farming.dm" +#include "modular_skyrat\modules\ashwalkers\code\buildings\ash_tendril.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\fuelwell.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\railroad.dm" -#include "modular_skyrat\modules\ashwalkers\code\buildings\tendril_corruption.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\tendril_cursing.dm" #include "modular_skyrat\modules\ashwalkers\code\clothing\ash_armour.dm" #include "modular_skyrat\modules\ashwalkers\code\clothing\hands.dm"