[MIRROR] Basic Mob Spiders I: Ability refactor [MDB IGNORE] (#19200)

* Basic Mob Spiders I: Ability refactor

* Update tgstation.dme

* Update tgstation.dme

* Update tgstation.dme

* Update tgstation.dme

* Update tgstation.dme

* Update tgstation.dme

---------

Co-authored-by: Jacquerel <hnevard@gmail.com>
Co-authored-by: KathrinBailey <53862927+KathrinBailey@users.noreply.github.com>
Co-authored-by: KathrinBailey <kat892@outlook.com>
This commit is contained in:
SkyratBot
2023-02-22 19:49:39 +01:00
committed by GitHub
parent 5f1fe0a0a9
commit bb9b68a88d
11 changed files with 380 additions and 389 deletions
+1
View File
@@ -3,3 +3,4 @@
#define DOAFTER_SOURCE_SURVIVALPEN "doafter_survivalpen"
#define DOAFTER_SOURCE_GETTING_UP "doafter_gettingup"
#define DOAFTER_SOURCE_CLIMBING_LADDER "doafter_climbingladder"
#define DOAFTER_SOURCE_SPIDER "doafter_spider"
+3 -3
View File
@@ -17,7 +17,7 @@
/// Visual indicators upon the character of the owner of this mutation
var/static/list/visual_indicators = list()
/// The path of action we grant to our user on mutation gain
var/datum/action/cooldown/spell/power_path
var/datum/action/cooldown/power_path
/// Which mutation layer to use
var/layer_used = MUTATIONS_LAYER
/// To restrict mutation to only certain species
@@ -180,7 +180,7 @@
/datum/mutation/human/proc/modify()
if(modified || !power_path || !owner)
return
var/datum/action/cooldown/spell/modified_power = locate(power_path) in owner.actions
var/datum/action/cooldown/modified_power = locate(power_path) in owner.actions
if(!modified_power)
CRASH("Genetic mutation [type] called modify(), but could not find a action to modify!")
modified_power.cooldown_time *= GET_MUTATION_ENERGY(src) // Doesn't do anything for mutations with energy_coeff unset
@@ -217,7 +217,7 @@
if(!ispath(power_path) || !owner)
return FALSE
var/datum/action/cooldown/spell/new_power = new power_path(src)
var/datum/action/cooldown/new_power = new power_path(src)
new_power.background_icon_state = "bg_tech_blue"
new_power.base_background_icon_state = new_power.background_icon_state
new_power.active_background_icon_state = "[new_power.base_background_icon_state]_active"
+4 -38
View File
@@ -5,20 +5,20 @@
quality = POSITIVE
text_gain_indication = "<span class='notice'>Your skin feels webby.</span>"
instability = 15
power_path = /datum/action/cooldown/spell/lay_genetic_web
power_path = /datum/action/cooldown/lay_web/genetic
energy_coeff = 1
/datum/mutation/human/webbing/modify()
. = ..()
var/datum/action/cooldown/spell/lay_genetic_web/to_modify =.
var/datum/action/cooldown/lay_web/genetic/to_modify = .
if(!istype(to_modify)) // null or invalid
return
if(GET_MUTATION_ENERGY(src) == 1) //energetic chromosome outputs a value less than 1 when present, 1 by default
if(GET_MUTATION_ENERGY(src) == 1) // Energetic chromosome outputs a value less than 1 when present, 1 by default
to_modify.webbing_time = initial(to_modify.webbing_time)
return
to_modify.webbing_time = 2 SECONDS
to_modify.webbing_time = 2 SECONDS // Spin webs faster but not more often
/datum/mutation/human/webbing/on_acquiring(mob/living/carbon/human/owner)
if(..())
@@ -29,37 +29,3 @@
if(..())
return
REMOVE_TRAIT(owner, TRAIT_WEB_WEAVER, GENETIC_MUTATION)
// In the future this could be unified with the spider's web action
/datum/action/cooldown/spell/lay_genetic_web
name = "Lay Web"
desc = "Drops a web. Only you will be able to traverse your web easily, making it pretty good for keeping you safe."
button_icon = 'icons/mob/actions/actions_genetic.dmi'
button_icon_state = "lay_web"
cooldown_time = 4 SECONDS //the same time to lay a web
spell_requirements = NONE
/// How long it takes to lay a web
var/webbing_time = 4 SECONDS
/// The path of web that we create
var/web_path = /obj/structure/spider/stickyweb/genetic
/datum/action/cooldown/spell/lay_genetic_web/cast(atom/cast_on)
var/turf/web_spot = cast_on.loc
if(!isturf(web_spot) || (locate(web_path) in web_spot))
to_chat(cast_on, span_warning("You can't lay webs here!"))
reset_spell_cooldown()
return FALSE
cast_on.visible_message(
span_notice("[cast_on] begins to secrete a sticky substance."),
span_notice("You begin to lay a web."),
)
if(!do_after(cast_on, webbing_time, target = web_spot))
to_chat(cast_on, span_warning("Your web spinning was interrupted!"))
return
new web_path(web_spot, cast_on)
return ..()
+4 -3
View File
@@ -43,8 +43,9 @@
return
if(!HAS_TRAIT(user,TRAIT_WEB_WEAVER))
return
user.visible_message(span_notice("[user] begins weaving [src] into cloth."), span_notice("You begin weaving [src] into cloth."))
user.balloon_alert_to_viewers("weaving...")
if(!do_after(user, 2 SECONDS))
user.balloon_alert(user, "interrupted!")
return
qdel(src)
var/obj/item/stack/sheet/cloth/woven_cloth = new /obj/item/stack/sheet/cloth
@@ -67,7 +68,7 @@
if(istype(mover.pulledby, /mob/living/simple_animal/hostile/giant_spider))
return TRUE
if(prob(50))
to_chat(mover, span_danger("You get stuck in \the [src] for a moment."))
balloon_alert(mover, "stuck in web!")
return FALSE
else if(isprojectile(mover))
return prob(30)
@@ -95,7 +96,7 @@
if(mover.pulledby == allowed_mob)
return TRUE
if(prob(50))
to_chat(mover, span_danger("You get stuck in \the [src] for a moment."))
balloon_alert(mover, "stuck in web!")
return FALSE
else if(isprojectile(mover))
return prob(30)
@@ -0,0 +1,70 @@
/**
* Sets a directive to be given to all future spiders created by the user.
* This will be overwritten if used again.
*/
/datum/action/set_spider_directive
name = "Set Directive"
desc = "Set a directive for your future children to follow."
button_icon = 'icons/mob/actions/actions_animal.dmi'
button_icon_state = "directive"
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
check_flags = AB_CHECK_CONSCIOUS
/// Current directive to apply
var/current_directive = ""
/datum/action/set_spider_directive/Trigger(trigger_flags)
. = ..()
if(!.)
return
var/new_directive = tgui_input_text(owner, "Enter the new directive", "Create directive", "[current_directive]")
if(isnull(new_directive) || QDELETED(src) || QDELETED(owner) || !IsAvailable(feedback = TRUE))
return FALSE
current_directive = new_directive
message_admins("[ADMIN_LOOKUPFLW(owner)] set its directive to: '[current_directive]'.")
owner.log_message("set its directive to: '[current_directive]'.", LOG_GAME)
return TRUE
/**
* Sends a message to all currently living spiders.
*/
/datum/action/command_spiders
name = "Command"
desc = "Send a command to all living spiders."
button_icon = 'icons/mob/actions/actions_animal.dmi'
button_icon_state = "command"
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
check_flags = AB_CHECK_CONSCIOUS
/datum/action/command_spiders/Trigger(trigger_flags)
. = ..()
if(!.)
return
var/input = tgui_input_text(owner, "Input a command for your legions to follow.", "Command")
if(!input || QDELETED(src) || QDELETED(owner) || !IsAvailable(feedback = TRUE))
return FALSE
spider_command(owner, input)
return TRUE
/**
* Sends a message to all spiders from the target.
*
* Allows the user to send a message to all spiders that exist. Ghosts will also see the message.
* Arguments:
* * user - The spider sending the message
* * message - The message to be sent
*/
/datum/action/command_spiders/proc/spider_command(mob/living/user, message)
if(!message)
return
var/my_message = span_spider("<b>Command from [user]:</b> [message]")
for(var/mob/living/simple_animal/hostile/giant_spider/spider as anything in GLOB.spidermobs)
to_chat(spider, my_message)
for(var/ghost in GLOB.dead_mob_list)
var/link = FOLLOW_LINK(ghost, user)
to_chat(ghost, "[link] [my_message]")
user.log_talk(message, LOG_SAY, tag = "spider command")
@@ -0,0 +1,82 @@
/datum/action/lay_eggs
name = "Lay Eggs"
desc = "Lay a cluster of eggs, which will soon grow into a normal spider."
button_icon = 'icons/mob/actions/actions_animal.dmi'
button_icon_state = "lay_eggs"
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
check_flags = AB_CHECK_CONSCIOUS
///How long it takes for a broodmother to lay eggs.
var/egg_lay_time = 12 SECONDS
///The type of egg we create
var/egg_type = /obj/effect/mob_spawn/ghost_role/spider
/datum/action/lay_eggs/Grant(mob/grant_to)
. = ..()
if (!owner)
return
RegisterSignals(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED), PROC_REF(update_status_on_signal))
/datum/action/lay_eggs/Remove(mob/removed_from)
. = ..()
UnregisterSignal(removed_from, list(COMSIG_MOVABLE_MOVED, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED))
/datum/action/lay_eggs/IsAvailable(feedback = FALSE)
. = ..()
if(!.)
return FALSE
if(DOING_INTERACTION(owner, DOAFTER_SOURCE_SPIDER))
if (feedback)
owner.balloon_alert(owner, "busy!")
return FALSE
var/obj/structure/spider/eggcluster/eggs = locate() in get_turf(owner)
if(eggs)
if (feedback)
owner.balloon_alert(owner, "already eggs here!")
return FALSE
return TRUE
/datum/action/lay_eggs/Trigger(trigger_flags)
. = ..()
if (!.)
return
owner.balloon_alert_to_viewers("laying eggs...")
if(do_after(owner, egg_lay_time, target = get_turf(owner), interaction_key = DOAFTER_SOURCE_SPIDER))
var/obj/structure/spider/eggcluster/eggs = locate() in get_turf(owner)
if(eggs)
owner.balloon_alert(owner, "already eggs here!")
else
lay_egg()
else
owner.balloon_alert(owner, "interrupted!")
build_all_button_icons(UPDATE_BUTTON_STATUS)
/datum/action/lay_eggs/proc/lay_egg()
var/obj/effect/mob_spawn/ghost_role/spider/new_eggs = new egg_type(get_turf(owner))
new_eggs.faction = owner.faction
var/datum/action/set_spider_directive/spider_directive = locate() in owner.actions
if (spider_directive)
new_eggs.directive = spider_directive.current_directive
/datum/action/lay_eggs/enriched
name = "Lay Enriched Eggs"
desc = "Lay a cluster of eggs, which will soon grow into a greater spider. Requires you drain a human per cluster of these eggs."
button_icon_state = "lay_enriched_eggs"
egg_type = /obj/effect/mob_spawn/ghost_role/spider/enriched
/// How many charges we have to make eggs
var/charges = 0
/datum/action/lay_eggs/enriched/IsAvailable(feedback = FALSE)
. = ..()
if (!.)
return FALSE
if (charges <= 0)
if (feedback)
owner.balloon_alert(owner, "must feed first!")
return FALSE
return TRUE
/datum/action/lay_eggs/enriched/lay_egg()
charges--
return ..()
@@ -0,0 +1,85 @@
/// Make a sticky web under yourself for area fortification
/datum/action/cooldown/lay_web
name = "Spin Web"
desc = "Spin a web to slow down potential prey."
button_icon = 'icons/mob/actions/actions_animal.dmi'
button_icon_state = "lay_web"
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
check_flags = AB_CHECK_CONSCIOUS
cooldown_time = 0 SECONDS
/// How long it takes to lay a web
var/webbing_time = 4 SECONDS
/datum/action/cooldown/lay_web/Grant(mob/grant_to)
. = ..()
if (!owner)
return
RegisterSignals(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED), PROC_REF(update_status_on_signal))
/datum/action/cooldown/lay_web/Remove(mob/removed_from)
. = ..()
UnregisterSignal(removed_from, list(COMSIG_MOVABLE_MOVED, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED))
/datum/action/cooldown/lay_web/IsAvailable(feedback = FALSE)
. = ..()
if(!.)
return FALSE
if(DOING_INTERACTION(owner, DOAFTER_SOURCE_SPIDER))
if (feedback)
owner.balloon_alert(owner, "busy!")
return FALSE
if(!isturf(owner.loc))
if (feedback)
owner.balloon_alert(owner, "invalid location!")
return FALSE
if(obstructed_by_other_web())
if (feedback)
owner.balloon_alert(owner, "already webbed!")
return FALSE
return TRUE
/// Returns true if there's a web we can't put stuff on in our turf
/datum/action/cooldown/lay_web/proc/obstructed_by_other_web()
return !!(locate(/obj/structure/spider/stickyweb) in get_turf(owner))
/datum/action/cooldown/lay_web/Activate()
. = ..()
var/turf/spider_turf = get_turf(owner)
var/obj/structure/spider/stickyweb/web = locate() in spider_turf
if(web)
owner.balloon_alert_to_viewers("sealing web...")
else
owner.balloon_alert_to_viewers("spinning web...")
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!")
build_all_button_icons()
/// Creates a web in the current turf
/datum/action/cooldown/lay_web/proc/plant_web(turf/target_turf, obj/structure/spider/stickyweb/existing_web)
new /obj/structure/spider/stickyweb(target_turf)
/// Variant for genetics, created webs only allow the creator passage
/datum/action/cooldown/lay_web/genetic
desc = "Spin a web. Only you will be able to traverse your web easily."
cooldown_time = 4 SECONDS //the same time to lay a web
/datum/action/cooldown/lay_web/genetic/plant_web(turf/target_turf, obj/structure/spider/stickyweb/existing_web)
new /obj/structure/spider/stickyweb/genetic(target_turf, owner)
/// Variant which allows webs to be stacked into walls
/datum/action/cooldown/lay_web/sealer
desc = "Spin a web to slow down potential prey. Webs can be stacked to make solid structures."
/datum/action/cooldown/lay_web/sealer/plant_web(turf/target_turf, obj/structure/spider/stickyweb/existing_web)
if (existing_web)
qdel(existing_web)
new /obj/structure/spider/stickyweb/sealed(target_turf)
return
new /obj/structure/spider/stickyweb(target_turf)
/datum/action/cooldown/lay_web/sealer/obstructed_by_other_web()
return !!(locate(/obj/structure/spider/stickyweb/sealed) in get_turf(owner))
@@ -0,0 +1,110 @@
/datum/action/cooldown/wrap
name = "Wrap"
desc = "Wrap something or someone in a cocoon. \
If it's a human or similar species, you'll also consume them. \
Consuming a wrapped victim can empower your egg-laying abilities. \
Activate this ability and then click on an adjacent target to begin wrapping them."
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
button_icon = 'icons/mob/actions/actions_animal.dmi'
button_icon_state = "wrap_0"
check_flags = AB_CHECK_CONSCIOUS
click_to_activate = TRUE
ranged_mousepointer = 'icons/effects/mouse_pointers/wrap_target.dmi'
/// The time it takes to wrap something.
var/wrap_time = 5 SECONDS
/datum/action/cooldown/wrap/Grant(mob/grant_to)
. = ..()
if (!owner)
return
RegisterSignals(owner, list(COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED), PROC_REF(update_status_on_signal))
/datum/action/cooldown/wrap/Remove(mob/removed_from)
. = ..()
UnregisterSignal(removed_from, list(COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED))
/datum/action/cooldown/wrap/IsAvailable(feedback = FALSE)
. = ..()
if(!. || owner.incapacitated())
return FALSE
if(DOING_INTERACTION(owner, DOAFTER_SOURCE_SPIDER))
if (feedback)
owner.balloon_alert(owner, "busy!")
return FALSE
return TRUE
/datum/action/cooldown/wrap/set_click_ability(mob/on_who)
. = ..()
if(!.)
return
on_who.balloon_alert(on_who, "prepared to wrap")
button_icon_state = "wrap_1"
build_all_button_icons()
/datum/action/cooldown/wrap/unset_click_ability(mob/on_who, refund_cooldown = TRUE)
. = ..()
if(!.)
return
if (refund_cooldown)
on_who.balloon_alert(on_who, "wrap cancelled")
button_icon_state = "wrap_0"
build_all_button_icons()
/datum/action/cooldown/wrap/Activate(atom/to_wrap)
if(!owner.Adjacent(to_wrap))
owner.balloon_alert(owner, "must be closer!")
return FALSE
if(!ismovable(to_wrap) || to_wrap == owner)
return FALSE
if(isspider(to_wrap))
owner.balloon_alert(owner, "can't wrap spiders!")
return FALSE
var/atom/movable/target_movable = to_wrap
if(target_movable.anchored)
return FALSE
StartCooldown(wrap_time)
INVOKE_ASYNC(src, PROC_REF(cocoon), to_wrap)
return TRUE
/datum/action/cooldown/wrap/proc/cocoon(atom/movable/to_wrap)
owner.visible_message(
span_notice("[owner] begins to secrete a sticky substance around [to_wrap]."),
span_notice("You begin wrapping [to_wrap] into a cocoon."),
)
if(do_after(owner, wrap_time, target = to_wrap, interaction_key = DOAFTER_SOURCE_SPIDER))
wrap_target(to_wrap)
else
owner.balloon_alert(owner, "interrupted!")
/datum/action/cooldown/wrap/proc/wrap_target(atom/movable/to_wrap)
var/obj/structure/spider/cocoon/casing = new(to_wrap.loc)
if(isliving(to_wrap))
var/mob/living/living_wrapped = to_wrap
// You get a point every time you consume a living player, even if they've been consumed before.
// You only get a point for any individual corpse once, so you can't keep breaking it out and eating it again.
if(ishuman(living_wrapped) && (living_wrapped.stat != DEAD || !HAS_TRAIT(living_wrapped, TRAIT_SPIDER_CONSUMED)))
var/datum/action/lay_eggs/enriched/egg_power = locate() in owner.actions
if(egg_power)
egg_power.charges++
egg_power.build_all_button_icons()
owner.visible_message(
span_danger("[owner] sticks a proboscis into [living_wrapped] and sucks a viscous substance out."),
span_notice("You suck the nutriment out of [living_wrapped], feeding you enough to lay a cluster of enriched eggs."),
)
ADD_TRAIT(living_wrapped, TRAIT_SPIDER_CONSUMED, TRAIT_GENERIC)
living_wrapped.investigate_log("has been killed by being wrapped in a cocoon.", INVESTIGATE_DEATHS)
living_wrapped.death() //you just ate them, they're dead.
log_combat(owner, living_wrapped, "spider cocooned")
else
to_chat(owner, span_warning("[living_wrapped] is not edible!"))
to_wrap.forceMove(casing)
if(to_wrap.density || ismob(to_wrap))
casing.icon_state = pick("cocoon_large1", "cocoon_large2", "cocoon_large3")
@@ -1,5 +1,3 @@
#define INTERACTION_SPIDER_KEY "spider_key"
/**
* # Giant Spider
*
@@ -55,8 +53,8 @@
var/poison_type = /datum/reagent/toxin/hunterspider
///How quickly the spider can place down webbing. One is base speed, larger numbers are slower.
var/web_speed = 1
///Whether or not the spider can create sealed webs.
var/web_sealer = FALSE
///What action is used to lay webs, some spiders have a version which can turn webs into walls.
var/web_type = /datum/action/cooldown/lay_web
///The message that the mother spider left for this spider when the egg was layed.
var/directive = ""
/// Short description of what this mob is capable of, for radial menu uses
@@ -64,7 +62,8 @@
/mob/living/simple_animal/hostile/giant_spider/Initialize(mapload)
. = ..()
var/datum/action/innate/spider/lay_web/webbing = new(src)
var/datum/action/cooldown/lay_web/webbing = new web_type(src)
webbing.webbing_time *= web_speed
webbing.Grant(src)
if(poison_per_bite)
@@ -137,7 +136,7 @@
melee_damage_lower = 5
melee_damage_upper = 10
web_speed = 0.25
web_sealer = TRUE
web_type = /datum/action/cooldown/lay_web/sealer
menu_description = "Support spider variant specializing in healing their brethren and placing webbings very swiftly, but has very low amount of health and deals low damage."
///The health HUD applied to the mob.
var/health_hud = DATA_HUD_MEDICAL_ADVANCED
@@ -148,7 +147,7 @@
datahud.show_to(src)
/mob/living/simple_animal/hostile/giant_spider/nurse/AttackingTarget()
if(DOING_INTERACTION(src, INTERACTION_SPIDER_KEY))
if(DOING_INTERACTION(src, DOAFTER_SOURCE_SPIDER))
return
if(!isspider(target))
return ..()
@@ -167,7 +166,7 @@
span_notice("You begin wrapping the wounds of [hurt_spider]."),
)
if(!do_after(src, 2 SECONDS, target = hurt_spider, interaction_key = INTERACTION_SPIDER_KEY))
if(!do_after(src, 2 SECONDS, target = hurt_spider, interaction_key = DOAFTER_SOURCE_SPIDER))
return
hurt_spider.heal_overall_damage(20, 20)
@@ -279,7 +278,7 @@
melee_damage_upper = 15
gold_core_spawnable = NO_SPAWN
web_speed = 0.5
web_sealer = TRUE
web_type = /datum/action/cooldown/lay_web/sealer
menu_description = "Royal spider variant specializing in reproduction and leadership, but has very low amount of health and deals low damage."
/mob/living/simple_animal/hostile/giant_spider/midwife/Initialize(mapload)
@@ -287,340 +286,18 @@
var/datum/action/cooldown/wrap/wrapping = new(src)
wrapping.Grant(src)
var/datum/action/innate/spider/lay_eggs/make_eggs = new(src)
var/datum/action/lay_eggs/make_eggs = new(src)
make_eggs.Grant(src)
var/datum/action/innate/spider/lay_eggs/enriched/make_better_eggs = new(src)
var/datum/action/lay_eggs/enriched/make_better_eggs = new(src)
make_better_eggs.Grant(src)
var/datum/action/innate/spider/set_directive/give_orders = new(src)
var/datum/action/set_spider_directive/give_orders = new(src)
give_orders.Grant(src)
var/datum/action/innate/spider/comm/not_hivemind_talk = new(src)
var/datum/action/command_spiders/not_hivemind_talk = new(src)
not_hivemind_talk.Grant(src)
/datum/action/innate/spider
button_icon = 'icons/mob/actions/actions_animal.dmi'
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
/datum/action/innate/spider/lay_web // Todo: Unify this with the genetics power
name = "Spin Web"
desc = "Spin a web to slow down potential prey."
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "lay_web"
/datum/action/innate/spider/lay_web/Grant(mob/grant_to)
. = ..()
if (!owner)
return
RegisterSignals(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED), PROC_REF(update_status_on_signal))
/datum/action/innate/spider/lay_web/Remove(mob/removed_from)
. = ..()
UnregisterSignal(removed_from, list(COMSIG_MOVABLE_MOVED, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED))
/datum/action/innate/spider/lay_web/IsAvailable(feedback = FALSE)
. = ..()
if(!.)
return FALSE
if(!isspider(owner))
return FALSE
if(DOING_INTERACTION(owner, INTERACTION_SPIDER_KEY))
return FALSE
if(!isturf(owner.loc))
return FALSE
var/mob/living/simple_animal/hostile/giant_spider/spider = owner
var/obj/structure/spider/stickyweb/web = locate() in get_turf(spider)
if(web && (!spider.web_sealer || istype(web, /obj/structure/spider/stickyweb/sealed)))
if (feedback)
owner.balloon_alert(owner, "already webbed!")
return FALSE
return TRUE
/datum/action/innate/spider/lay_web/Activate()
var/turf/spider_turf = get_turf(owner)
var/mob/living/simple_animal/hostile/giant_spider/spider = owner
var/obj/structure/spider/stickyweb/web = locate() in spider_turf
if(web)
spider.visible_message(
span_notice("[spider] begins to pack more webbing onto the web."),
span_notice("You begin to seal the web."),
)
else
spider.visible_message(
span_notice("[spider] begins to secrete a sticky substance."),
span_notice("You begin to lay a web."),
)
spider.stop_automated_movement = TRUE
if(do_after(spider, 4 SECONDS * spider.web_speed, target = spider_turf, interaction_key = INTERACTION_SPIDER_KEY))
if(spider.loc == spider_turf)
if(web)
qdel(web)
new /obj/structure/spider/stickyweb/sealed(spider_turf)
new /obj/structure/spider/stickyweb(spider_turf)
build_all_button_icons()
spider.stop_automated_movement = FALSE
/datum/action/cooldown/wrap
name = "Wrap"
desc = "Wrap something or someone in a cocoon. If it's a human or similar species, \
you'll also consume them, allowing you to lay enriched eggs. \
Activate this ability and then click on an adjacent target to begin wrapping them."
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
button_icon = 'icons/mob/actions/actions_animal.dmi'
button_icon_state = "wrap_0"
check_flags = AB_CHECK_CONSCIOUS
click_to_activate = TRUE
ranged_mousepointer = 'icons/effects/mouse_pointers/wrap_target.dmi'
/// The time it takes to wrap something.
var/wrap_time = 5 SECONDS
/datum/action/cooldown/wrap/Grant(mob/grant_to)
. = ..()
if (!owner)
return
RegisterSignals(owner, list(COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED), PROC_REF(update_status_on_signal))
/datum/action/cooldown/wrap/Remove(mob/removed_from)
. = ..()
UnregisterSignal(removed_from, list(COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED))
/datum/action/cooldown/wrap/IsAvailable(feedback = FALSE)
. = ..()
if(!.)
return FALSE
if(owner.incapacitated())
return FALSE
if(DOING_INTERACTION(owner, INTERACTION_SPIDER_KEY))
return FALSE
return TRUE
/datum/action/cooldown/wrap/set_click_ability(mob/on_who)
. = ..()
if(!.)
return
on_who.balloon_alert(on_who, "prepared to wrap")
button_icon_state = "wrap_1"
build_all_button_icons()
/datum/action/cooldown/wrap/unset_click_ability(mob/on_who, refund_cooldown = TRUE)
. = ..()
if(!.)
return
if (refund_cooldown)
on_who.balloon_alert(on_who, "wrap cancelled")
button_icon_state = "wrap_0"
build_all_button_icons()
/datum/action/cooldown/wrap/Activate(atom/to_wrap)
if(!owner.Adjacent(to_wrap))
owner.balloon_alert(owner, "must be closer!")
return FALSE
if(!ismob(to_wrap) && !isobj(to_wrap))
return FALSE
if(to_wrap == owner)
return FALSE
if(isspider(to_wrap))
owner.balloon_alert(owner, "can't wrap spiders!")
return FALSE
var/atom/movable/target_movable = to_wrap
if(target_movable.anchored)
return FALSE
StartCooldown(wrap_time)
INVOKE_ASYNC(src, PROC_REF(cocoon), to_wrap)
return TRUE
/datum/action/cooldown/wrap/proc/cocoon(atom/movable/to_wrap)
owner.visible_message(
span_notice("[owner] begins to secrete a sticky substance around [to_wrap]."),
span_notice("You begin wrapping [to_wrap] into a cocoon."),
)
var/mob/living/simple_animal/animal_owner = owner
if(istype(animal_owner))
animal_owner.stop_automated_movement = TRUE
if(do_after(owner, wrap_time, target = to_wrap, interaction_key = INTERACTION_SPIDER_KEY))
wrap_target(to_wrap)
if(istype(animal_owner))
animal_owner.stop_automated_movement = FALSE
/datum/action/cooldown/wrap/proc/wrap_target(atom/movable/to_wrap)
var/obj/structure/spider/cocoon/casing = new(to_wrap.loc)
if(isliving(to_wrap))
var/mob/living/living_wrapped = to_wrap
// You get a point every time you consume a living player, even if they've been consumed before.
// You only get a point for any individual corpse once, so you can't keep breaking it out and eating it again.
if(ishuman(living_wrapped) && (living_wrapped.stat != DEAD || !HAS_TRAIT(living_wrapped, TRAIT_SPIDER_CONSUMED)))
var/datum/action/innate/spider/lay_eggs/enriched/egg_power = locate() in owner.actions
if(egg_power)
egg_power.charges++
egg_power.build_all_button_icons()
owner.visible_message(
span_danger("[owner] sticks a proboscis into [living_wrapped] and sucks a viscous substance out."),
span_notice("You suck the nutriment out of [living_wrapped], feeding you enough to lay a cluster of enriched eggs."),
)
ADD_TRAIT(living_wrapped, TRAIT_SPIDER_CONSUMED, TRAIT_GENERIC)
living_wrapped.investigate_log("has been killed by being wrapped in a cocoon.", INVESTIGATE_DEATHS)
living_wrapped.death() //you just ate them, they're dead.
log_combat(owner, living_wrapped, "spider cocooned")
else
to_chat(owner, span_warning("[living_wrapped] is not edible!"))
to_wrap.forceMove(casing)
if(to_wrap.density || ismob(to_wrap))
casing.icon_state = pick("cocoon_large1", "cocoon_large2", "cocoon_large3")
/datum/action/innate/spider/lay_eggs
name = "Lay Eggs"
desc = "Lay a cluster of eggs, which will soon grow into a normal spider."
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "lay_eggs"
///How long it takes for a broodmother to lay eggs.
var/egg_lay_time = 12 SECONDS
///The type of egg we create
var/egg_type = /obj/effect/mob_spawn/ghost_role/spider
/datum/action/innate/spider/lay_eggs/Grant(mob/grant_to)
. = ..()
if (!owner)
return
RegisterSignals(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED), PROC_REF(update_status_on_signal))
/datum/action/innate/spider/lay_eggs/Remove(mob/removed_from)
. = ..()
UnregisterSignal(removed_from, list(COMSIG_MOVABLE_MOVED, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED))
/datum/action/innate/spider/lay_eggs/IsAvailable(feedback = FALSE)
. = ..()
if(!.)
return FALSE
if(!isspider(owner))
return FALSE
if(DOING_INTERACTION(owner, INTERACTION_SPIDER_KEY))
return FALSE
var/obj/structure/spider/eggcluster/eggs = locate() in get_turf(owner)
if(eggs)
if (feedback)
owner.balloon_alert(owner, "already eggs here!")
return FALSE
return TRUE
/datum/action/innate/spider/lay_eggs/Activate()
owner.visible_message(
span_notice("[owner] begins to lay a cluster of eggs."),
span_notice("You begin to lay a cluster of eggs."),
)
var/mob/living/simple_animal/hostile/giant_spider/spider = owner
spider.stop_automated_movement = TRUE
if(do_after(owner, egg_lay_time, target = get_turf(owner), interaction_key = INTERACTION_SPIDER_KEY))
var/obj/structure/spider/eggcluster/eggs = locate() in get_turf(owner)
if(eggs)
owner.balloon_alert(owner, "already eggs here!")
else
lay_egg()
build_all_button_icons(UPDATE_BUTTON_STATUS)
spider.stop_automated_movement = FALSE
/datum/action/innate/spider/lay_eggs/proc/lay_egg()
var/mob/living/simple_animal/hostile/giant_spider/spider = owner
var/obj/effect/mob_spawn/ghost_role/spider/new_eggs = new egg_type(get_turf(owner))
new_eggs.directive = spider.directive
new_eggs.faction = spider.faction
/datum/action/innate/spider/lay_eggs/enriched
name = "Lay Enriched Eggs"
desc = "Lay a cluster of eggs, which will soon grow into a greater spider. Requires you drain a human per cluster of these eggs."
button_icon_state = "lay_enriched_eggs"
egg_type = /obj/effect/mob_spawn/ghost_role/spider/enriched
/// How many charges we have to make eggs
var/charges = 0
/datum/action/innate/spider/lay_eggs/enriched/IsAvailable(feedback = FALSE)
. = ..()
if (!.)
return FALSE
if (charges <= 0)
if (feedback)
owner.balloon_alert(owner, "must feed first!")
return FALSE
return TRUE
/datum/action/innate/spider/lay_eggs/enriched/lay_egg()
charges--
return ..()
/datum/action/innate/spider/set_directive
name = "Set Directive"
desc = "Set a directive for your children to follow."
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "directive"
/datum/action/innate/spider/set_directive/IsAvailable(feedback = FALSE)
return ..() && isspider(owner)
/datum/action/innate/spider/set_directive/Activate()
var/mob/living/simple_animal/hostile/giant_spider/spider = owner
spider.directive = tgui_input_text(spider, "Enter the new directive", "Create directive", "[spider.directive]")
if(isnull(spider.directive) || QDELETED(src) || QDELETED(owner) || !IsAvailable(feedback = TRUE))
return FALSE
message_admins("[ADMIN_LOOKUPFLW(owner)] set its directive to: '[spider.directive]'.")
owner.log_message("set its directive to: '[spider.directive]'.", LOG_GAME)
return TRUE
/datum/action/innate/spider/comm
name = "Command"
desc = "Send a command to all living spiders."
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "command"
/datum/action/innate/spider/comm/IsAvailable(feedback = FALSE)
return ..() && istype(owner, /mob/living/simple_animal/hostile/giant_spider/midwife)
/datum/action/innate/spider/comm/Trigger(trigger_flags)
var/input = tgui_input_text(owner, "Input a command for your legions to follow.", "Command")
if(!input || QDELETED(src) || QDELETED(owner) || !IsAvailable(feedback = TRUE))
return FALSE
spider_command(owner, input)
return TRUE
/**
* Sends a message to all spiders from the target.
*
* Allows the user to send a message to all spiders that exist. Ghosts will also see the message.
* Arguments:
* * user - The spider sending the message
* * message - The message to be sent
*/
/datum/action/innate/spider/comm/proc/spider_command(mob/living/user, message)
if(!message)
return
var/my_message
my_message = span_spider("<b>Command from [user]:</b> [message]")
for(var/mob/living/simple_animal/hostile/giant_spider/spider as anything in GLOB.spidermobs)
to_chat(spider, my_message)
for(var/ghost in GLOB.dead_mob_list)
var/link = FOLLOW_LINK(ghost, user)
to_chat(ghost, "[link] [my_message]")
user.log_talk(message, LOG_SAY, tag = "spider command")
/**
* # Giant Ice Spider
*
@@ -744,7 +421,7 @@
blood_spawn_chance = 5)
/mob/living/simple_animal/hostile/giant_spider/hunter/flesh/AttackingTarget()
if(DOING_INTERACTION(src, INTERACTION_SPIDER_KEY))
if(DOING_INTERACTION(src, DOAFTER_SOURCE_SPIDER))
return
if(src == target)
if(on_fire)
@@ -754,7 +431,7 @@
to_chat(src, span_warning("You're not injured, there's no reason to heal."))
return
visible_message(span_notice("[src] begins mending themselves..."),span_notice("You begin mending your wounds..."))
if(do_after(src, 2 SECONDS, target = src, interaction_key = INTERACTION_SPIDER_KEY))
if(do_after(src, 2 SECONDS, target = src, interaction_key = DOAFTER_SOURCE_SPIDER))
heal_overall_damage(maxHealth * 0.5, maxHealth * 0.5)
new /obj/effect/temp_visual/heal(get_turf(src), "#80F5FF")
visible_message(span_notice("[src]'s wounds mend together."),span_notice("You mend your wounds together."))
@@ -776,5 +453,3 @@
/mob/living/simple_animal/hostile/giant_spider/viper/wizard/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
#undef INTERACTION_SPIDER_KEY
@@ -102,14 +102,11 @@
to_chat(user, span_warning("\The [src] is not ready to hatch yet!"))
return FALSE
/obj/effect/mob_spawn/ghost_role/spider/equip(mob/living/simple_animal/hostile/giant_spider/spawned_spider)
if(spawned_spider)
spawned_spider.directive = directive
/obj/effect/mob_spawn/ghost_role/spider/special(mob/user)
. = ..()
/obj/effect/mob_spawn/ghost_role/spider/special(mob/living/simple_animal/hostile/giant_spider/spawned_mob, mob/mob_possessor)
spawned_mob.directive = directive
egg.spawner = null
QDEL_NULL(egg)
return ..()
/obj/effect/mob_spawn/ghost_role/spider/enriched
name = "enriched egg cluster"
+4
View File
@@ -3833,6 +3833,10 @@
#include "code\modules\mob\living\basic\space_fauna\carp\magicarp.dm"
#include "code\modules\mob\living\basic\space_fauna\carp\megacarp.dm"
#include "code\modules\mob\living\basic\space_fauna\faithless\faithless.dm"
#include "code\modules\mob\living\basic\space_fauna\giant_spider\spider_abilities\hivemind.dm"
#include "code\modules\mob\living\basic\space_fauna\giant_spider\spider_abilities\lay_eggs.dm"
#include "code\modules\mob\living\basic\space_fauna\giant_spider\spider_abilities\web.dm"
#include "code\modules\mob\living\basic\space_fauna\giant_spider\spider_abilities\wrap.dm"
#include "code\modules\mob\living\basic\syndicate\syndicate.dm"
#include "code\modules\mob\living\basic\syndicate\syndicate_ai.dm"
#include "code\modules\mob\living\basic\vermin\axolotl.dm"