From 32e84471a9abc636a76bf260c60e20c8b47d42b1 Mon Sep 17 00:00:00 2001 From: RandomGamer123 <31096837+RandomGamer123@users.noreply.github.com> Date: Thu, 21 Jul 2022 05:22:14 -0400 Subject: [PATCH] [READY] Venus human trap fix 3.0: Allow ghosts to possess them even when obscured, use better spawning system (#67418) Moves venus human traps to use the /obj/effect/mob_spawn/ghost_role/ system of spawning similar to things like spiders. Effects of this include: Having a notification to ghosts when one is ready to be spawned, having venus human traps respect role bans, and allowing them to be possessed from the ghost role menu. Also adds poll ignore and role defines for venus human traps. To clarify in more detail: Venus human traps spawn by flowering kudzu (with a 10% chance). However, they spawn immediately under the kudzu and can't be clicked on (even with the alt-click menu), so they can only be possessed by a ghost only if the kudzu above them gets destroyed or they get moved out of the kudzu. Instead of just fiddling around with layers, moving venus human traps to the same ghost role system used by other ghost roles helps centralize them and make it more obvious that a) you can possess them to begin with, and b) how to possess them --- code/__DEFINES/role_preferences.dm | 1 + code/_globalvars/lists/poll_ignore.dm | 2 + .../job_types/spawner/venus_human_trap.dm | 3 + code/modules/jobs/jobs.dm | 1 + .../simple_animal/hostile/venus_human_trap.dm | 58 ++++++------------- .../mob_spawn/ghost_roles/venus_human_trap.dm | 54 +++++++++++++++++ tgstation.dme | 2 + 7 files changed, 80 insertions(+), 41 deletions(-) create mode 100644 code/modules/jobs/job_types/spawner/venus_human_trap.dm create mode 100644 code/modules/mob_spawn/ghost_roles/venus_human_trap.dm diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 0f74b31c249..17f3ef4b505 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -97,6 +97,7 @@ #define ROLE_MAINTENANCE_DRONE "Maintenance Drone" #define ROLE_BATTLECRUISER_CREW "Battlecruiser Crew" #define ROLE_BATTLECRUISER_CAPTAIN "Battlecruiser Captain" +#define ROLE_VENUSHUMANTRAP "Venus Human Trap" /// This defines the antagonists you can operate with in the settings. diff --git a/code/_globalvars/lists/poll_ignore.dm b/code/_globalvars/lists/poll_ignore.dm index fb237b37903..db5a23e7685 100644 --- a/code/_globalvars/lists/poll_ignore.dm +++ b/code/_globalvars/lists/poll_ignore.dm @@ -20,6 +20,7 @@ #define POLL_IGNORE_CONTRACTOR_SUPPORT "contractor_support" #define POLL_IGNORE_ACADEMY_WIZARD "academy_wizard" #define POLL_IGNORE_PAI "pai" +#define POLL_IGNORE_VENUSHUMANTRAP "venus_human_trap" GLOBAL_LIST_INIT(poll_ignore_desc, list( @@ -43,6 +44,7 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list( POLL_IGNORE_CONTRACTOR_SUPPORT = "Contractor Support Unit", POLL_IGNORE_ACADEMY_WIZARD = "Academy Wizard Defender", POLL_IGNORE_PAI = JOB_PERSONAL_AI, + POLL_IGNORE_VENUSHUMANTRAP = "Venus Human Traps", )) GLOBAL_LIST_INIT(poll_ignore, init_poll_ignore()) diff --git a/code/modules/jobs/job_types/spawner/venus_human_trap.dm b/code/modules/jobs/job_types/spawner/venus_human_trap.dm new file mode 100644 index 00000000000..6fd354a4989 --- /dev/null +++ b/code/modules/jobs/job_types/spawner/venus_human_trap.dm @@ -0,0 +1,3 @@ +/datum/job/venus_human_trap + title = ROLE_VENUSHUMANTRAP + policy_index = ROLE_VENUSHUMANTRAP diff --git a/code/modules/jobs/jobs.dm b/code/modules/jobs/jobs.dm index 7658050da8e..5eea0d7fc46 100644 --- a/code/modules/jobs/jobs.dm +++ b/code/modules/jobs/jobs.dm @@ -21,6 +21,7 @@ GLOBAL_LIST_INIT(exp_specialmap, list( ROLE_SPACE_BAR_PATRON, ROLE_LAVALAND_SYNDICATE, ROLE_MAINTENANCE_DRONE, + ROLE_VENUSHUMANTRAP, ROLE_GHOST_ROLE, ), // Ghost roles EXP_TYPE_GHOST = list() // dead people, observers diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 13815f1a4e3..dec507046e1 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -9,6 +9,7 @@ * Once it grows a venus human trap, the bud itself will destroy itself. * */ +/// Flower bud structure that ghost role spawns, actual spawn logic handled by /obj/effect/mob_spawn/ghost_role/venus_human_trap /obj/structure/alien/resin/flower_bud //inheriting basic attack/damage stuff from alien structures name = "flower bud" desc = "A large pulsating plant..." @@ -32,8 +33,13 @@ var/list/vines = list() + /// The spawner that actually handles spawning the ghost role in + var/obj/effect/mob_spawn/ghost_role/venus_human_trap/spawner + /obj/structure/alien/resin/flower_bud/Initialize(mapload) . = ..() + spawner = new(get_turf(loc)) + spawner.flower_bud = src countdown = new(src) var/list/anchors = list() anchors += locate(x-2,y+2,z) @@ -55,21 +61,18 @@ /obj/structure/alien/resin/flower_bud/Destroy() QDEL_LIST(vines) + QDEL_NULL(countdown) + if(spawner) // anti harddel checks + if(!QDELETED(spawner)) + qdel(spawner) + spawner = null return ..() -/** - * Spawns a venus human trap, then qdels itself. - * - * Displays a message, spawns a human venus trap, then qdels itself. - */ +/// Tells the spawner that the venus human trap is ready /obj/structure/alien/resin/flower_bud/proc/bear_fruit() visible_message(span_danger("The plant has borne fruit!")) - var/mob/living/simple_animal/hostile/venus_human_trap/spawned_human_trap = new(get_turf(src)) - if(trait_flags & SPACEVINE_HEAT_RESISTANT) - spawned_human_trap.unsuitable_heat_damage = 0 - if(trait_flags & SPACEVINE_COLD_RESISTANT) - spawned_human_trap.unsuitable_cold_damage = 0 - qdel(src) + if(spawner) + spawner.bear_fruit() /obj/structure/alien/resin/flower_bud/proc/progress_growth() growth_icon++ @@ -78,6 +81,9 @@ return addtimer(CALLBACK(src, .proc/progress_growth), growth_time/4) +/obj/structure/alien/resin/flower_bud/attack_ghost(mob/user) + spawner.attack_ghost(user) + /obj/effect/ebeam/vine name = "thick vine" mouse_opacity = MOUSE_OPACITY_ICON @@ -192,41 +198,11 @@ L.Knockdown(1 SECONDS) ranged_cooldown = world.time + ranged_cooldown_time -/mob/living/simple_animal/hostile/venus_human_trap/Login() - . = ..() - to_chat(src, span_boldwarning("You are a venus human trap! Protect the kudzu at all costs, and feast on those who oppose you!")) - -/mob/living/simple_animal/hostile/venus_human_trap/attack_ghost(mob/user) - . = ..() - if(. || !(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER)) - return - humanize_plant(user) - /mob/living/simple_animal/hostile/venus_human_trap/Destroy() for(var/datum/beam/vine as anything in vines) qdel(vine) // reference is automatically deleted by remove_vine return ..() -/** - * Sets a ghost to control the plant if the plant is eligible - * - * Asks the interacting ghost if they would like to control the plant. - * If they answer yes, and another ghost hasn't taken control, sets the ghost to control the plant. - * Arguments: - * * mob/user - The ghost to possibly control the plant - */ -/mob/living/simple_animal/hostile/venus_human_trap/proc/humanize_plant(mob/user) - if(key || !playable_plant || stat) - return - var/plant_ask = tgui_alert(usr,"Become a venus human trap?", "Are you reverse vegan?", list("Yes", "No")) - if(plant_ask == "No" || QDELETED(src)) - return - if(key) - to_chat(user, span_warning("Someone else already took this plant!")) - return - key = user.key - log_game("[key_name(src)] took control of [name].") - /** * Manages how the vines should affect the things they're attached to. * diff --git a/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm b/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm new file mode 100644 index 00000000000..6d1e0b9e438 --- /dev/null +++ b/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm @@ -0,0 +1,54 @@ +/// Handles logic for ghost spawning code, visible object in game is handled by /obj/structure/alien/resin/flower_bud +/obj/effect/mob_spawn/ghost_role/venus_human_trap + name = "flower bud" + desc = "A large pulsating plant..." + icon = 'icons/effects/spacevines.dmi' + icon_state = "bud0" + mob_type = /mob/living/simple_animal/hostile/venus_human_trap + prompt_name = "venus human trap" + you_are_text = "You are a venus human trap." + flavour_text = "You are a venus human trap! Protect the kudzu at all costs, and feast on those who oppose you!" + faction = list("hostile","vines","plants") + spawner_job_path = /datum/job/venus_human_trap + /// Physical structure housing the spawner + var/obj/structure/alien/resin/flower_bud/flower_bud + /// Used to determine when to notify ghosts + var/ready = FALSE + +/obj/effect/mob_spawn/ghost_role/venus_human_trap/Destroy() + if(flower_bud) // anti harddel checks + if(!QDELETED(flower_bud)) + qdel(flower_bud) + flower_bud = null + return ..() + +/obj/effect/mob_spawn/ghost_role/venus_human_trap/equip(mob/living/simple_animal/hostile/venus_human_trap/spawned_human_trap) + if(spawned_human_trap && flower_bud) + if(flower_bud.trait_flags & SPACEVINE_HEAT_RESISTANT) + spawned_human_trap.unsuitable_heat_damage = 0 + if(flower_bud.trait_flags & SPACEVINE_COLD_RESISTANT) + spawned_human_trap.unsuitable_cold_damage = 0 + +/// Called when the attached flower bud has borne fruit (ie. is ready) +/obj/effect/mob_spawn/ghost_role/venus_human_trap/proc/bear_fruit() + ready = TRUE + notify_ghosts("[src] has borne fruit!", null, enter_link = "(Click to play)", source = src, action = NOTIFY_ATTACK, ignore_key = POLL_IGNORE_VENUSHUMANTRAP) + +/obj/effect/mob_spawn/ghost_role/venus_human_trap/Topic(href, href_list) + . = ..() + if(.) + return + if(href_list["activate"]) + var/mob/dead/observer/ghost = usr + if(istype(ghost)) + ghost.ManualFollow(src) + attack_ghost(ghost) + +/obj/effect/mob_spawn/ghost_role/venus_human_trap/allow_spawn(mob/user, silent = FALSE) + . = ..() + if(!.) + return FALSE + if(!ready) + if(!silent) + to_chat(user, span_warning("\The [src] has not borne fruit yet!")) + return FALSE diff --git a/tgstation.dme b/tgstation.dme index b5231fa191d..8b51550deb1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3184,6 +3184,7 @@ #include "code\modules\jobs\job_types\spawner\spider.dm" #include "code\modules\jobs\job_types\spawner\syndicate_cybersun.dm" #include "code\modules\jobs\job_types\spawner\syndicate_cybersun_captain.dm" +#include "code\modules\jobs\job_types\spawner\venus_human_trap.dm" #include "code\modules\jobs\job_types\spawner\zombie.dm" #include "code\modules\keybindings\bindings_atom.dm" #include "code\modules\keybindings\bindings_client.dm" @@ -3693,6 +3694,7 @@ #include "code\modules\mob_spawn\ghost_roles\space_roles.dm" #include "code\modules\mob_spawn\ghost_roles\spider_roles.dm" #include "code\modules\mob_spawn\ghost_roles\unused_roles.dm" +#include "code\modules\mob_spawn\ghost_roles\venus_human_trap.dm" #include "code\modules\mod\mod_actions.dm" #include "code\modules\mod\mod_activation.dm" #include "code\modules\mod\mod_ai.dm"