mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-12 08:36:00 +01:00
[MIRROR] Station Trait: Spider Infestation [MDB IGNORE] (#19813)
* Station Trait: Spider Infestation (#73893) ## About The Pull Request Hate having your cables eaten by mice? Nanotrasen have heard your complaints and settled on a natural, _organic_, and eco-friendly solution. When this station trait is active, roundstart and event mouse spawns have a chance to instead be replaced with duct spiders (both will exist, it doesn't remove mice). Duct spiders are largely harmless to humans, actively hunt other maintenance creatures (such as mice), and have only one _tiny_ downside.  These mobs can also sometimes be spawned by a minor scrubber clog event. As a side note, all spider basic mobs with AI (except Araneus) will now try to automatically fill a small area around them with webs. Also I made it so that mobs will ignore their random_walking behaviour if they're engaged in a `do_after`, just in case. ## Why It's Good For The Game Adds a little bit of variety to things which can slightly annoy you in maintenance. Spiders will automatically make places they live in look like spiders live there. ## Changelog 🆑 add: A station trait which sometimes populates maintenance with small spiders. You can wear them as a hat if you wanted to have a spider on your head for some reason. add: Spider mobs will automatically start webbing up their environment. /🆑 * Station Trait: Spider Infestation --------- Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
@@ -73,6 +73,7 @@
|
||||
var/datum/action/cooldown/lay_web/webbing = new web_type(src)
|
||||
webbing.webbing_time *= web_speed
|
||||
webbing.Grant(src)
|
||||
ai_controller.blackboard[BB_SPIDER_WEB_ACTION] = WEAKREF(webbing)
|
||||
|
||||
/mob/living/basic/giant_spider/Login()
|
||||
. = ..()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// For now, essentially just a Simple Hostile but room for expansion
|
||||
/// Attacks people it can see, spins webs if it can't see anything to attack.
|
||||
/datum/ai_controller/basic_controller/giant_spider
|
||||
blackboard = list(
|
||||
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(),
|
||||
@@ -13,6 +13,8 @@
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
/datum/ai_planning_subtree/random_speech/insect, // Space spiders are taxonomically insects not arachnids, don't DM me
|
||||
/datum/ai_planning_subtree/find_unwebbed_turf,
|
||||
/datum/ai_planning_subtree/spin_web,
|
||||
)
|
||||
|
||||
/// Giant spider which won't attack structures
|
||||
@@ -21,9 +23,11 @@
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
/datum/ai_planning_subtree/random_speech/insect,
|
||||
/datum/ai_planning_subtree/find_unwebbed_turf,
|
||||
/datum/ai_planning_subtree/spin_web,
|
||||
)
|
||||
|
||||
/// Used by Araneus, who only attacks those who attack first
|
||||
/// Used by Araneus, who only attacks those who attack first. He is house-trained and will not web up the HoS office.
|
||||
/datum/ai_controller/basic_controller/giant_spider/retaliate
|
||||
blackboard = list(
|
||||
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction(),
|
||||
@@ -35,3 +39,22 @@
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
/datum/ai_planning_subtree/random_speech/insect,
|
||||
)
|
||||
|
||||
/// Retaliates, hunts other maintenance creatures, runs away from larger attackers, and spins webs.
|
||||
/datum/ai_controller/basic_controller/giant_spider/pest
|
||||
blackboard = list(
|
||||
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/of_size/ours_or_smaller(), // Hunt mobs our size
|
||||
BB_FLEE_TARGETTING_DATUM = new /datum/targetting_datum/basic/of_size/larger(), // Run away from mobs bigger than we are
|
||||
BB_BASIC_MOB_FLEEING = TRUE,
|
||||
)
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/target_retaliate/to_flee,
|
||||
/datum/ai_planning_subtree/flee_target/from_flee_key,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
/datum/ai_planning_subtree/random_speech/insect,
|
||||
/datum/ai_planning_subtree/find_unwebbed_turf,
|
||||
/datum/ai_planning_subtree/spin_web,
|
||||
)
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
if(do_after(owner, webbing_time, target = spider_turf, interaction_key = DOAFTER_SOURCE_SPIDER) && owner.loc == spider_turf)
|
||||
plant_web(spider_turf, web)
|
||||
else
|
||||
owner.balloon_alert(owner, "interrupted!")
|
||||
owner?.balloon_alert(owner, "interrupted!") // Null check because we might have been interrupted via being disintegrated
|
||||
build_all_button_icons()
|
||||
|
||||
/// Creates a web in the current turf
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/// Search for a nearby location to put webs on
|
||||
/datum/ai_planning_subtree/find_unwebbed_turf
|
||||
|
||||
/datum/ai_planning_subtree/find_unwebbed_turf/SelectBehaviors(datum/ai_controller/controller, delta_time)
|
||||
controller.queue_behavior(/datum/ai_behavior/find_unwebbed_turf)
|
||||
|
||||
/// Find an unwebbed nearby turf and store it
|
||||
/datum/ai_behavior/find_unwebbed_turf
|
||||
action_cooldown = 5 SECONDS
|
||||
/// Where do we store the target data
|
||||
var/target_key = BB_SPIDER_WEB_TARGET
|
||||
/// How far do we look for unwebbed turfs?
|
||||
var/scan_range = 3
|
||||
|
||||
/datum/ai_behavior/find_unwebbed_turf/perform(delta_time, datum/ai_controller/controller)
|
||||
. = ..()
|
||||
var/mob/living/spider = controller.pawn
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/atom/current_target = weak_target?.resolve()
|
||||
if (current_target && !(locate(/obj/structure/spider/stickyweb) in current_target))
|
||||
finish_action(controller, succeeded = FALSE) // Already got a target
|
||||
return
|
||||
|
||||
controller.blackboard[target_key] = null
|
||||
var/turf/our_turf = get_turf(spider)
|
||||
if (is_valid_web_turf(our_turf))
|
||||
controller.blackboard[target_key] = WEAKREF(our_turf)
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
return
|
||||
|
||||
var/list/potential_turfs = list()
|
||||
for(var/turf/turf_in_view in oview(scan_range, our_turf))
|
||||
if (!is_valid_web_turf(turf_in_view))
|
||||
continue
|
||||
potential_turfs += turf_in_view
|
||||
|
||||
if (!length(potential_turfs))
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
return
|
||||
|
||||
controller.blackboard[target_key] = WEAKREF(get_closest_atom(/turf/, potential_turfs, our_turf))
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
|
||||
/datum/ai_behavior/find_unwebbed_turf/proc/is_valid_web_turf(turf/target_turf, mob/living/spider)
|
||||
if (locate(/obj/structure/spider/stickyweb) in target_turf)
|
||||
return FALSE
|
||||
return !target_turf.is_blocked_turf(source_atom = spider)
|
||||
|
||||
/// Run the spin web behaviour if we have an ability to use for it
|
||||
/datum/ai_planning_subtree/spin_web
|
||||
/// Key where the web spinning action is stored
|
||||
var/action_key = BB_SPIDER_WEB_ACTION
|
||||
/// Key where the target turf is stored
|
||||
var/target_key = BB_SPIDER_WEB_TARGET
|
||||
|
||||
/datum/ai_planning_subtree/spin_web/SelectBehaviors(datum/ai_controller/controller, delta_time)
|
||||
var/datum/weakref/weak_action = controller.blackboard[action_key]
|
||||
var/datum/action/cooldown/using_action = weak_action?.resolve()
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/turf/target_turf = weak_target?.resolve()
|
||||
if (!using_action || !target_turf)
|
||||
return
|
||||
controller.queue_behavior(/datum/ai_behavior/spin_web, action_key, target_key)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
/// Move to an unwebbed nearby turf and web it up
|
||||
/datum/ai_behavior/spin_web
|
||||
action_cooldown = 15 SECONDS // We don't want them doing this too quickly
|
||||
required_distance = 0
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
|
||||
/datum/ai_behavior/spin_web/setup(datum/ai_controller/controller, action_key, target_key)
|
||||
var/datum/weakref/weak_action = controller.blackboard[action_key]
|
||||
var/datum/action/cooldown/web_action = weak_action?.resolve()
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/turf/target_turf = weak_target?.resolve()
|
||||
if (!web_action || !target_turf)
|
||||
return FALSE
|
||||
|
||||
set_movement_target(controller, target_turf)
|
||||
return ..()
|
||||
|
||||
/datum/ai_behavior/spin_web/perform(delta_time, datum/ai_controller/controller, action_key, target_key)
|
||||
. = ..()
|
||||
var/datum/weakref/weak_action = controller.blackboard[action_key]
|
||||
var/datum/action/cooldown/web_action = weak_action?.resolve()
|
||||
finish_action(controller, succeeded = web_action?.Trigger(), action_key = action_key, target_key = target_key)
|
||||
|
||||
/datum/ai_behavior/spin_web/finish_action(datum/ai_controller/controller, succeeded, action_key, target_key)
|
||||
controller.blackboard[target_key] = null
|
||||
return ..()
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* # Spider Hunter
|
||||
* ### Spider Hunter
|
||||
* A subtype of the giant spider which is faster, has toxin injection, but less health and damage.
|
||||
* This spider is only slightly slower than a human.
|
||||
*/
|
||||
@@ -19,7 +19,7 @@
|
||||
menu_description = "Fast spider variant specializing in catching running prey and toxin injection, but has less health and damage."
|
||||
|
||||
/**
|
||||
* # Spider Nurse
|
||||
* ### Spider Nurse
|
||||
*
|
||||
* A subtype of the giant spider which specializes in support skills.
|
||||
* Nurses can place down webbing in a quarter of the time that other species can and can wrap other spiders' wounds, healing them.
|
||||
@@ -56,7 +56,7 @@
|
||||
)
|
||||
|
||||
/**
|
||||
* # Tarantula
|
||||
* ### Tarantula
|
||||
*
|
||||
* A subtype of the giant spider which specializes in pure strength and staying power.
|
||||
* Is slowed down when not on webbing, but can lunge to throw off attackers and possibly to stun them.
|
||||
@@ -97,7 +97,7 @@
|
||||
charge.Trigger(target = atom_target)
|
||||
|
||||
/**
|
||||
* # Spider Viper
|
||||
* ### Spider Viper
|
||||
*
|
||||
* A subtype of the giant spider which specializes in speed and poison.
|
||||
* Injects a deadlier toxin than other spiders, moves extremely fast, but has a limited amount of health.
|
||||
@@ -120,7 +120,7 @@
|
||||
menu_description = "Assassin spider variant with an unmatched speed and very deadly poison, but has very low amount of health and damage."
|
||||
|
||||
/**
|
||||
* # Spider Broodmother
|
||||
* ### Spider Broodmother
|
||||
*
|
||||
* A subtype of the giant spider which is the crux of a spider horde, and the way which it grows.
|
||||
* Has very little offensive capabilities but can lay eggs at any time to create more basic spiders.
|
||||
@@ -161,7 +161,7 @@
|
||||
not_hivemind_talk.Grant(src)
|
||||
|
||||
/**
|
||||
* # Giant Ice Spider
|
||||
* ### Giant Ice Spider
|
||||
*
|
||||
* A subtype of the giant spider which is immune to temperature damage, unlike its normal counterpart.
|
||||
* Currently unused in the game unless spawned by admins.
|
||||
@@ -176,7 +176,7 @@
|
||||
menu_description = "Versatile ice spider variant for frontline combat with high health and damage. Immune to temperature damage."
|
||||
|
||||
/**
|
||||
* # Ice Nurse Spider
|
||||
* ### Ice Nurse Spider
|
||||
*
|
||||
* A temperature-proof nurse spider. Also unused.
|
||||
*/
|
||||
@@ -190,7 +190,7 @@
|
||||
menu_description = "Support ice spider variant specializing in healing their brethren and placing webbings very swiftly, but has very low amount of health and deals low damage. Immune to temperature damage."
|
||||
|
||||
/**
|
||||
* # Ice Hunter Spider
|
||||
* ### Ice Hunter Spider
|
||||
*
|
||||
* A temperature-proof hunter with chilling venom. Also unused.
|
||||
*/
|
||||
@@ -205,7 +205,7 @@
|
||||
menu_description = "Fast ice spider variant specializing in catching running prey and frost oil injection, but has less health and damage. Immune to temperature damage."
|
||||
|
||||
/**
|
||||
* # Scrawny Hunter Spider
|
||||
* ### Scrawny Hunter Spider
|
||||
*
|
||||
* A hunter spider that trades damage for health, unable to smash enviroments.
|
||||
* Used as a minor threat in abandoned places, such as areas in maintenance or a ruin.
|
||||
@@ -221,7 +221,7 @@
|
||||
ai_controller = /datum/ai_controller/basic_controller/giant_spider/weak
|
||||
|
||||
/**
|
||||
* # Scrawny Tarantula
|
||||
* ### Scrawny Tarantula
|
||||
*
|
||||
* A weaker version of the Tarantula, unable to smash enviroments.
|
||||
* Used as a moderately strong but slow threat in abandoned places, such as areas in maintenance or a ruin.
|
||||
@@ -237,7 +237,7 @@
|
||||
ai_controller = /datum/ai_controller/basic_controller/giant_spider/weak
|
||||
|
||||
/**
|
||||
* # Scrawny Nurse Spider
|
||||
* ### Scrawny Nurse Spider
|
||||
*
|
||||
* A weaker version of the nurse spider with reduced health, unable to smash enviroments.
|
||||
* Mainly used as a weak threat in abandoned places, such as areas in maintenance or a ruin.
|
||||
@@ -252,7 +252,7 @@
|
||||
ai_controller = /datum/ai_controller/basic_controller/giant_spider/weak
|
||||
|
||||
/**
|
||||
* # Flesh Spider
|
||||
* ### Flesh Spider
|
||||
*
|
||||
* A subtype of giant spider which only occurs from changelings.
|
||||
* Has the base stats of a hunter, but they can heal themselves and spin webs faster.
|
||||
@@ -291,7 +291,7 @@
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* # Viper Spider (Wizard)
|
||||
* ### Viper Spider (Wizard)
|
||||
*
|
||||
* A spider form for wizards. Has the viper spider's extreme speed and strong venom, with additional health and vent crawling abilities.
|
||||
*/
|
||||
@@ -306,7 +306,7 @@
|
||||
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
||||
|
||||
/**
|
||||
* # Sergeant Araneus
|
||||
* ### Sergeant Araneus
|
||||
*
|
||||
* This friendly arachnid hangs out in the HoS office on some space stations. Better trained than an average officer and does not attack except in self-defence.
|
||||
*/
|
||||
@@ -327,3 +327,42 @@
|
||||
AddElement(/datum/element/pet_bonus, "chitters proudly!")
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
||||
|
||||
/**
|
||||
* ### Duct Spider
|
||||
*
|
||||
* A less giant spider which lives in the maintenance ducts and makes them annoying to traverse.
|
||||
*/
|
||||
/mob/living/basic/giant_spider/maintenance
|
||||
name = "duct spider"
|
||||
desc = "Nanotrasen's imported solution to mice, comes with its own problems."
|
||||
icon_state = "maint_spider"
|
||||
icon_living = "maint_spider"
|
||||
icon_dead = "maint_spider_dead"
|
||||
can_be_held = TRUE
|
||||
mob_size = MOB_SIZE_TINY
|
||||
held_w_class = WEIGHT_CLASS_TINY
|
||||
worn_slot_flags = ITEM_SLOT_HEAD
|
||||
head_icon = 'icons/mob/clothing/head/pets_head.dmi'
|
||||
density = FALSE
|
||||
pass_flags = PASSTABLE|PASSGRILLE|PASSMOB
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
maxHealth = 10
|
||||
health = 10
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 1
|
||||
speed = 0
|
||||
player_speed_modifier = 0
|
||||
web_speed = 0.25
|
||||
menu_description = "Fragile spider variant which is not good for much other than laying webs."
|
||||
response_harm_continuous = "splats"
|
||||
response_harm_simple = "splat"
|
||||
ai_controller = /datum/ai_controller/basic_controller/giant_spider/pest
|
||||
apply_spider_antag = FALSE
|
||||
|
||||
/mob/living/basic/giant_spider/maintenance/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
||||
AddElement(/datum/element/web_walker, /datum/movespeed_modifier/duct_spider_web)
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
AddElement(/datum/element/tiny_mob_hunter)
|
||||
|
||||
Reference in New Issue
Block a user