diff --git a/code/__DEFINES/span.dm b/code/__DEFINES/span.dm
index 17dfc830b63..2e237ce94ae 100644
--- a/code/__DEFINES/span.dm
+++ b/code/__DEFINES/span.dm
@@ -106,7 +106,8 @@
#define span_small(str) ("" + str + "")
#define span_smallnotice(str) ("" + str + "")
#define span_smallnoticeital(str) ("" + str + "")
-#define span_spider(str) ("" + str + "")
+#define span_spiderbroodmother(str) ("" + str + "")
+#define span_spiderscout(str) ("" + str + "")
#define span_suicide(str) ("" + str + "")
#define span_suppradio(str) ("" + str + "")
#define span_syndradio(str) ("" + str + "")
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index b12b77ba0b2..bd050f10f50 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -464,9 +464,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_ORBITING_FORBIDDEN "orbiting_forbidden"
/// Trait applied to mob/living to mark that spiders should not gain further enriched eggs from eating their corpse.
#define TRAIT_SPIDER_CONSUMED "spider_consumed"
-/// Whether we're sneaking, from the alien sneak ability.
-/// Maybe worth generalizing into a general "is sneaky" / "is stealth" trait in the future.
-#define TRAIT_ALIEN_SNEAK "sneaking_alien"
+/// Whether we're sneaking, from the creature sneak ability.
+#define TRAIT_SNEAK "sneaking_creatures"
/// Item still allows you to examine items while blind and actively held.
#define TRAIT_BLIND_TOOL "blind_tool"
diff --git a/code/datums/actions/mobs/charge.dm b/code/datums/actions/mobs/charge.dm
index 71e145a6720..9a49b465f07 100644
--- a/code/datums/actions/mobs/charge.dm
+++ b/code/datums/actions/mobs/charge.dm
@@ -173,6 +173,7 @@
cooldown_time = 6 SECONDS
charge_delay = 1.5 SECONDS
charge_distance = 4
+ melee_cooldown_time = 0
/// How long to shake for before charging
var/shake_duration = 1 SECONDS
/// Intensity of shaking animation
diff --git a/code/datums/actions/mobs/sneak.dm b/code/datums/actions/mobs/sneak.dm
new file mode 100644
index 00000000000..13ae5a784b8
--- /dev/null
+++ b/code/datums/actions/mobs/sneak.dm
@@ -0,0 +1,32 @@
+/datum/action/cooldown/sneak
+ name = "Sneak"
+ desc = "Sneak into the enviorment."
+ button_icon = 'icons/mob/actions/actions_animal.dmi'
+ button_icon_state = "sniper_zoom"
+ background_icon_state = "bg_alien"
+ overlay_icon_state = "bg_alien_border"
+ check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED | AB_CHECK_INCAPACITATED
+ /// The alpha we go to when sneaking.
+ var/sneak_alpha = 75
+
+/datum/action/cooldown/sneak/Remove(mob/living/remove_from)
+ if(HAS_TRAIT(remove_from, TRAIT_SNEAK))
+ remove_from.alpha = initial(remove_from.alpha)
+ REMOVE_TRAIT(remove_from, TRAIT_SNEAK, name)
+
+ return ..()
+
+/datum/action/cooldown/sneak/Activate(atom/target)
+ if(HAS_TRAIT(owner, TRAIT_SNEAK))
+ // It's safest to go to the initial alpha of the mob.
+ // Otherwise we get permanent invisbility exploits.
+ owner.alpha = initial(owner.alpha)
+ to_chat(owner, span_noticealien("You reveal yourself!"))
+ REMOVE_TRAIT(owner, TRAIT_SNEAK, name)
+
+ else
+ owner.alpha = sneak_alpha
+ to_chat(owner, span_noticealien("You blend into the enviorment..."))
+ ADD_TRAIT(owner, TRAIT_SNEAK, name)
+
+ return TRUE
diff --git a/code/datums/martial/mushpunch.dm b/code/datums/martial/mushpunch.dm
index 2809ef85ada..e56771b5bd8 100644
--- a/code/datums/martial/mushpunch.dm
+++ b/code/datums/martial/mushpunch.dm
@@ -4,9 +4,9 @@
/datum/martial_art/mushpunch/harm_act(mob/living/A, mob/living/D)
var/atk_verb
- to_chat(A, span_spider("You begin to wind up an attack..."))
+ to_chat(A, span_spiderbroodmother("You begin to wind up an attack..."))
if(!do_after(A, 2.5 SECONDS, target = D))
- to_chat(A, span_spider("Your attack was interrupted!"))
+ to_chat(A, span_spiderbroodmother("Your attack was interrupted!"))
return TRUE //martial art code was a mistake
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
atk_verb = pick("punch", "smash", "crack")
@@ -31,7 +31,7 @@
/obj/item/mushpunch/attack_self(mob/living/user)
if(!istype(user) || !user)
return
- var/message = span_spider("You devour [src], and a confluence of skill and power from the mushroom enhances your punches! You do need a short moment to charge these powerful punches.")
+ var/message = span_spiderbroodmother("You devour [src], and a confluence of skill and power from the mushroom enhances your punches! You do need a short moment to charge these powerful punches.")
to_chat(user, message)
var/datum/martial_art/mushpunch/mush = new(null)
mush.teach(user)
diff --git a/code/game/objects/effects/spiderwebs.dm b/code/game/objects/effects/spiderwebs.dm
index 608447dad8e..93d8fbbed0d 100644
--- a/code/game/objects/effects/spiderwebs.dm
+++ b/code/game/objects/effects/spiderwebs.dm
@@ -19,7 +19,7 @@
if(damage_flag == MELEE)
switch(damage_type)
if(BURN)
- damage_amount *= 2
+ damage_amount *= 1.25
if(BRUTE)
damage_amount *= 0.25
. = ..()
@@ -105,6 +105,38 @@
else if(isprojectile(mover))
return prob(30)
+/obj/structure/spider/solid
+ name = "solid web"
+ icon = 'icons/effects/effects.dmi'
+ desc = "A solid wall of web, thick enough to block air flow."
+ icon_state = "solidweb"
+ can_atmos_pass = ATMOS_PASS_NO
+ opacity = TRUE
+ density = TRUE
+ max_integrity = 90
+ plane = GAME_PLANE_UPPER
+ resistance_flags = FIRE_PROOF | FREEZE_PROOF
+
+/obj/structure/spider/solid/Initialize(mapload)
+ . = ..()
+ air_update_turf(TRUE, TRUE)
+
+/obj/structure/spider/passage
+ name = "web passage"
+ icon = 'icons/effects/effects.dmi'
+ desc = "A messy connection of webs blocking the other side, but not solid enough to prevent passage."
+ icon_state = "webpassage"
+ can_atmos_pass = ATMOS_PASS_NO
+ opacity = TRUE
+ max_integrity = 60
+ alpha = 200
+ plane = GAME_PLANE_UPPER
+ resistance_flags = FIRE_PROOF | FREEZE_PROOF
+
+/obj/structure/spider/passage/Initialize(mapload)
+ . = ..()
+ air_update_turf(TRUE, TRUE)
+
/obj/structure/spider/cocoon
name = "cocoon"
desc = "Something wrapped in silky spider web."
@@ -132,3 +164,41 @@
for(var/atom/movable/A in contents)
A.forceMove(T)
return ..()
+
+/obj/structure/spider/sticky
+ name = "sticky web"
+ icon = 'icons/effects/effects.dmi'
+ desc = "Extremely soft and sticky silk."
+ icon_state = "verystickyweb"
+ max_integrity = 20
+
+/obj/structure/spider/sticky/CanAllowThrough(atom/movable/mover, border_dir)
+ . = ..()
+ if(isspider(mover))
+ return TRUE
+ if(!isliving(mover))
+ return
+ if(isspider(mover.pulledby))
+ return TRUE
+ balloon_alert(mover, "stuck in web!")
+ return FALSE
+
+/obj/structure/spider/spikes
+ name = "web spikes"
+ icon = 'icons/effects/effects.dmi'
+ desc = "hardened silk formed into small yet deadly spikes."
+ icon_state = "webspikes1"
+ max_integrity = 40
+
+/obj/structure/spider/spikes/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/caltrop, min_damage = 20, max_damage = 30, flags = CALTROP_NOSTUN | CALTROP_BYPASS_SHOES)
+
+/obj/structure/spider/carcass
+ name = "web carcass"
+ icon = 'icons/effects/effects.dmi'
+ desc = "hardened silk formed into small yet deadly spikes."
+ icon_state = "webcarcass"
+ max_integrity = 125
+ density = TRUE
+ anchored = FALSE
diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider.dm
index 1ecc7d3deee..b62e42edc92 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider.dm
@@ -19,9 +19,9 @@
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
initial_language_holder = /datum/language_holder/spider
- speed = 4
- maxHealth = 80
- health = 80
+ speed = 5
+ maxHealth = 125
+ health = 125
damage_coeff = list(BRUTE = 1, BURN = 1.25, TOX = 1, CLONE = 1, STAMINA = 1, OXY = 1)
basic_mob_flags = FLAMMABLE_MOB
status_flags = NONE
@@ -57,7 +57,7 @@
/// 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
- var/menu_description = "Versatile spider variant for frontline combat with high health and damage."
+ var/menu_description = "Tanky and strong for the defense of the nest and other spiders."
/// If true then you shouldn't be told that you're a spider antagonist as soon as you are placed into this mob
var/apply_spider_antag = TRUE
diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_variants.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_variants.dm
index 408844b545b..f9186617584 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_variants.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_variants.dm
@@ -1,3 +1,62 @@
+/**
+ * ### Spider Ambush
+ * A subtype of the giant spider which is slower, stronger and able to sneak into its surroundings to pull pray aggressively.
+ * This spider is only slightly slower than a human.
+ */
+/mob/living/basic/giant_spider/ambush
+ name = "ambush spider"
+ desc = "Furry and white, it makes you shudder to look at it. This one has sparkling pink eyes."
+ icon_state = "ambush"
+ icon_living = "ambush"
+ icon_dead = "ambush_dead"
+ gender = FEMALE
+ maxHealth = 125
+ health = 125
+ obj_damage = 45
+ melee_damage_lower = 25
+ melee_damage_upper = 30
+ speed = 5
+ player_speed_modifier = -3.1
+ menu_description = "Slow spider variant specializing in stalking and ambushing prey, above avarage health and damage with a strong grip."
+
+/mob/living/basic/giant_spider/ambush/Initialize(mapload)
+ . = ..()
+ ADD_TRAIT(src, TRAIT_STRONG_GRABBER, INNATE_TRAIT)
+
+ AddElement(/datum/element/web_walker, /datum/movespeed_modifier/slow_web)
+
+ var/datum/action/cooldown/sneak/spider/sneak_web = new(src)
+ sneak_web.Grant(src)
+
+/**
+ * ### Spider Guard
+ * A subtype of the giant spider which is similar on every single way,
+ * This spider is only slightly slower than a human.
+ */
+/mob/living/basic/giant_spider/guard
+ name = "guard spider"
+ desc = "Furry and black, it makes you shudder to look at it. This one has deep red eyes."
+ icon_state = "guard"
+ icon_living = "guard"
+ icon_dead = "guard_dead"
+ gender = FEMALE
+ maxHealth = 160
+ health = 160
+ melee_damage_lower = 20
+ melee_damage_upper = 25
+ obj_damage = 45
+ speed = 5
+ player_speed_modifier = -4
+ menu_description = "Tanky and strong for the defense of the nest and other spiders."
+
+/mob/living/basic/giant_spider/guard/Initialize(mapload)
+ . = ..()
+
+ AddElement(/datum/element/web_walker, /datum/movespeed_modifier/average_web)
+
+ var/datum/action/cooldown/lay_web/web_carcass/carcass_web = new(src)
+ carcass_web.Grant(src)
+
/**
* ### Spider Hunter
* A subtype of the giant spider which is faster, has toxin injection, but less health and damage.
@@ -9,8 +68,8 @@
icon_state = "hunter"
icon_living = "hunter"
icon_dead = "hunter_dead"
- maxHealth = 50
- health = 50
+ maxHealth = 80
+ health = 80
melee_damage_lower = 15
melee_damage_upper = 20
poison_per_bite = 5
@@ -18,6 +77,41 @@
player_speed_modifier = -3.1
menu_description = "Fast spider variant specializing in catching running prey and toxin injection, but has less health and damage."
+/mob/living/basic/giant_spider/hunter/Initialize(mapload)
+ . = ..()
+
+ AddElement(/datum/element/web_walker, /datum/movespeed_modifier/fast_web)
+
+/**
+ * ### Spider Scout
+ * A subtype of the giant spider which is faster, has thermal vision, but less health and damage.
+ * This spider is only slightly faster than a human.
+ */
+/mob/living/basic/giant_spider/scout
+ name = "scout spider"
+ desc = "Furry and blueish black, it makes you shudder to look at it. This one has sparkling blue eyes."
+ icon_state = "scout"
+ icon_living = "scout"
+ icon_dead = "scout_dead"
+ maxHealth = 65
+ health = 65
+ obj_damage = 10
+ melee_damage_lower = 5
+ melee_damage_upper = 10
+ poison_per_bite = 10
+ poison_type = /datum/reagent/peaceborg/confuse
+ speed = 2.8
+ player_speed_modifier = -3.1
+ sight = SEE_SELF|SEE_MOBS
+ menu_description = "Fast spider variant specializing in scouting and alerting of prey, with the ability to travel in vents."
+
+/mob/living/basic/giant_spider/scout/Initialize(mapload)
+ . = ..()
+ ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
+
+ var/datum/action/command_spiders/communication_spiders/spiders_communication = new(src)
+ spiders_communication.Grant(src)
+
/**
* ### Spider Nurse
*
@@ -37,6 +131,8 @@
health = 40
melee_damage_lower = 5
melee_damage_upper = 10
+ speed = 4
+ player_speed_modifier = -3.1
web_speed = 0.25
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."
@@ -55,6 +151,62 @@
complete_text = "%SOURCE% wraps the wounds of %TARGET%.",\
)
+ AddElement(/datum/element/web_walker, /datum/movespeed_modifier/average_web)
+
+/**
+ * ### Tangle Spider
+ *
+ * A subtype of the giant spider which specializes in support skills.
+ * Tangle spiders can place down webbing in a quarter of the time that other species plus has an expanded arsenal of traps and web structures to place to benefit the nest.
+ * Note that it can heal itself.
+ */
+/mob/living/basic/giant_spider/tangle
+ name = "tangle spider"
+ desc = "Furry and brown, it makes you shudder to look at it. This one has dim brown eyes."
+ icon_state = "tangle"
+ icon_living = "tangle"
+ icon_dead = "tangle_dead"
+ gender = FEMALE
+ butcher_results = list(/obj/item/food/meat/slab/spider = 2, /obj/item/food/spiderleg = 8, /obj/item/food/spidereggs = 4)
+ maxHealth = 40
+ health = 40
+ melee_damage_lower = 1
+ melee_damage_upper = 1
+ poison_per_bite = 5
+ poison_type = /datum/reagent/toxin/acid
+ obj_damage = 40
+ web_speed = 0.25
+ speed = 4
+ player_speed_modifier = -3.1
+ web_type = /datum/action/cooldown/lay_web/sealer
+ menu_description = "Support spider variant specializing in contruction to protect their brethren, but has very low amount of health and deals low damage."
+
+/mob/living/basic/giant_spider/tangle/Initialize(mapload)
+ . = ..()
+ var/datum/action/cooldown/lay_web/solid_web/web_solid = new(src)
+ web_solid.Grant(src)
+
+ var/datum/action/cooldown/lay_web/web_passage/passage_web = new(src)
+ passage_web.Grant(src)
+
+ var/datum/action/cooldown/lay_web/web_spikes/spikes_web = new(src)
+ spikes_web.Grant(src)
+
+ var/datum/action/cooldown/lay_web/sticky_web/web_sticky = new(src)
+ web_sticky.Grant(src)
+
+ AddElement(/datum/element/web_walker, /datum/movespeed_modifier/average_web)
+
+ AddComponent(/datum/component/healing_touch,\
+ heal_brute = maxHealth * 0.5,\
+ heal_burn = maxHealth * 0.5,\
+ self_targetting = HEALING_TOUCH_SELF_ONLY,\
+ interaction_key = DOAFTER_SOURCE_SPIDER,\
+ valid_targets_typecache = typecacheof(list(/mob/living/basic/giant_spider/tangle)),\
+ action_text = "%SOURCE% begins mending themselves...",\
+ complete_text = "%SOURCE%'s wounds mend together.",\
+ )
+
/**
* ### Tarantula
*
@@ -86,7 +238,7 @@
charge = new /datum/action/cooldown/mob_cooldown/charge/basic_charge()
charge.Grant(src)
- AddElement(/datum/element/web_walker, /datum/movespeed_modifier/tarantula_web)
+ AddElement(/datum/element/web_walker, /datum/movespeed_modifier/slow_web)
/mob/living/basic/giant_spider/tarantula/Destroy()
QDEL_NULL(charge)
@@ -134,17 +286,31 @@
icon_state = "midwife"
icon_living = "midwife"
icon_dead = "midwife_dead"
- maxHealth = 60
- health = 60
+ maxHealth = 250
+ health = 250
melee_damage_lower = 10
melee_damage_upper = 15
+ speed = 4
+ player_speed_modifier = -3.1
gold_core_spawnable = NO_SPAWN
web_speed = 0.5
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."
+ menu_description = "Royal spider variant specializing in reproduction and leadership, deals low damage."
/mob/living/basic/giant_spider/midwife/Initialize(mapload)
. = ..()
+ var/datum/action/cooldown/lay_web/solid_web/web_solid = new(src)
+ web_solid.Grant(src)
+
+ var/datum/action/cooldown/lay_web/web_passage/passage_web = new(src)
+ passage_web.Grant(src)
+
+ var/datum/action/cooldown/lay_web/web_spikes/spikes_web = new(src)
+ spikes_web.Grant(src)
+
+ var/datum/action/cooldown/lay_web/sticky_web/web_sticky = new(src)
+ web_sticky.Grant(src)
+
var/datum/action/cooldown/wrap/wrapping = new(src)
wrapping.Grant(src)
@@ -160,6 +326,8 @@
var/datum/action/command_spiders/not_hivemind_talk = new(src)
not_hivemind_talk.Grant(src)
+ AddElement(/datum/element/web_walker, /datum/movespeed_modifier/average_web)
+
/**
* ### Giant Ice Spider
*
@@ -264,7 +432,9 @@
icon_living = "flesh_spider"
icon_dead = "flesh_spider_dead"
web_speed = 0.7
- menu_description = "Self-sufficient spider variant capable of healing themselves and producing webbbing fast, but has less health and damage."
+ maxHealth = 90
+ health = 90
+ menu_description = "Self-sufficient spider variant capable of healing themselves and producing webbbing fast."
/mob/living/basic/giant_spider/hunter/flesh/Initialize(mapload)
. = ..()
@@ -290,6 +460,14 @@
return FALSE
return TRUE
+/mob/living/basic/giant_spider/hunter/flesh/Initialize(mapload)
+ . = ..()
+ var/datum/action/cooldown/lay_web/web_spikes/spikes_web = new(src)
+ spikes_web.Grant(src)
+
+ var/datum/action/cooldown/lay_web/sticky_web/web_sticky = new(src)
+ web_sticky.Grant(src)
+
/**
* ### Viper Spider (Wizard)
*
@@ -364,6 +542,6 @@
/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/web_walker, /datum/movespeed_modifier/average_web)
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/tiny_mob_hunter)
diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/hivemind.dm b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/hivemind.dm
index 7eb3126877d..77ee38ed7c3 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/hivemind.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/hivemind.dm
@@ -51,7 +51,7 @@
return TRUE
/**
- * Sends a message to all spiders from the target.
+ * Sends a big 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:
@@ -61,10 +61,28 @@
/datum/action/command_spiders/proc/spider_command(mob/living/user, message)
if(!message)
return
- var/my_message = span_spider("Command from [user]: [message]")
+ var/my_message = format_message(user,message)
for(var/mob/living/basic/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")
+
+/**
+ * Formats the string to have an appropiate size and text color
+ */
+/datum/action/command_spiders/proc/format_message(mob/living/user, message)
+ return span_spiderbroodmother("Command from [user]: [message]")
+
+/**
+ * Sends a small message to all currently living spiders.
+ */
+/datum/action/command_spiders/communication_spiders
+ name = "Communication"
+ desc = "Send a report to all living spiders."
+ button_icon = 'icons/mob/actions/actions_animal.dmi'
+ button_icon_state = "message"
+
+/datum/action/command_spiders/communication_spiders/format_message(mob/living/user, message)
+ return span_spiderscout("Report from [user]: [message]")
diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/lay_eggs.dm b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/lay_eggs.dm
index 0fb1170c607..cd86a93f75d 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/lay_eggs.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/lay_eggs.dm
@@ -7,7 +7,7 @@
overlay_icon_state = "bg_alien_border"
check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED
///How long it takes for a broodmother to lay eggs.
- var/egg_lay_time = 12 SECONDS
+ var/egg_lay_time = 4 SECONDS
///The type of egg we create
var/egg_type = /obj/effect/mob_spawn/ghost_role/spider
diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/web.dm b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/web.dm
index 2ac43bb5487..bcc4a5f089c 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/web.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/web.dm
@@ -8,6 +8,7 @@
overlay_icon_state = "bg_alien_border"
check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED
cooldown_time = 0 SECONDS
+ melee_cooldown_time = 0
/// How long it takes to lay a web
var/webbing_time = 4 SECONDS
@@ -83,3 +84,69 @@
/datum/action/cooldown/lay_web/sealer/obstructed_by_other_web()
return !!(locate(/obj/structure/spider/stickyweb/sealed) in get_turf(owner))
+
+/datum/action/cooldown/lay_web/solid_web
+ name = "Spin Solid Web"
+ desc = "Spin a web to slow down potential prey."
+ button_icon_state = "lay_solid_web"
+ cooldown_time = 0 SECONDS
+ webbing_time = 5 SECONDS
+
+/datum/action/cooldown/lay_web/solid_web/obstructed_by_other_web()
+ return !!(locate(/obj/structure/spider/solid) in get_turf(owner))
+
+/datum/action/cooldown/lay_web/solid_web/plant_web(turf/target_turf, obj/structure/spider/stickyweb/existing_web)
+ new /obj/structure/spider/solid(target_turf)
+
+/datum/action/cooldown/lay_web/web_passage
+ name = "Spin Web Passage"
+ desc = "Spin a web passage to hide the nest from prey view."
+ button_icon_state = "lay_web_passage"
+ cooldown_time = 0 SECONDS
+ webbing_time = 4 SECONDS
+
+/datum/action/cooldown/lay_web/web_passage/obstructed_by_other_web()
+ return !!(locate(/obj/structure/spider/passage) in get_turf(owner))
+
+/datum/action/cooldown/lay_web/web_passage/plant_web(turf/target_turf, obj/structure/spider/stickyweb/existing_web)
+ new /obj/structure/spider/passage(target_turf)
+
+
+/datum/action/cooldown/lay_web/sticky_web
+ name = "Spin Sticky Web"
+ desc = "Spin a web to stick intruders in place."
+ button_icon_state = "lay_sticky_web"
+ cooldown_time = 20 SECONDS
+ webbing_time = 3 SECONDS
+
+/datum/action/cooldown/lay_web/sticky_web/obstructed_by_other_web()
+ return !!(locate(/obj/structure/spider/sticky) in get_turf(owner))
+
+/datum/action/cooldown/lay_web/sticky_web/plant_web(turf/target_turf, obj/structure/spider/stickyweb/existing_web)
+ new /obj/structure/spider/sticky(target_turf)
+
+/datum/action/cooldown/lay_web/web_spikes
+ name = "Spin Web Spikes"
+ desc = "Spin a spikes made out of web to stop intruders."
+ button_icon_state = "lay_web_spikes"
+ cooldown_time = 40 SECONDS
+ webbing_time = 3 SECONDS
+
+/datum/action/cooldown/lay_web/web_spikes/obstructed_by_other_web()
+ return !!(locate(/obj/structure/spider/spikes) in get_turf(owner))
+
+/datum/action/cooldown/lay_web/web_spikes/plant_web(turf/target_turf, obj/structure/spider/stickyweb/existing_web)
+ new /obj/structure/spider/spikes(target_turf)
+
+/datum/action/cooldown/lay_web/web_carcass
+ name = "leave carcass"
+ desc = "Shed your skin and leave a web carcass behind."
+ button_icon_state = "shed_web_carcass"
+ cooldown_time = 60 SECONDS
+ webbing_time = 0 SECONDS
+
+/datum/action/cooldown/lay_web/web_carcass/obstructed_by_other_web()
+ return !!(locate(/obj/structure/spider/carcass) in get_turf(owner))
+
+/datum/action/cooldown/lay_web/web_carcass/plant_web(turf/target_turf, obj/structure/spider/stickyweb/existing_web)
+ new /obj/structure/spider/carcass(target_turf)
diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/web_sneak.dm b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/web_sneak.dm
new file mode 100644
index 00000000000..adee0bb0ca0
--- /dev/null
+++ b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/web_sneak.dm
@@ -0,0 +1,7 @@
+/datum/action/cooldown/sneak/spider
+ name = "Sneak"
+ desc = "Blend into the webs to stalk your prey."
+ button_icon = 'icons/mob/actions/actions_animal.dmi'
+ button_icon_state = "web_sneak"
+ background_icon_state = "bg_alien"
+ overlay_icon_state = "bg_alien_border"
diff --git a/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling.dm b/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling.dm
index a62f3515599..4813db8848b 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling.dm
@@ -18,12 +18,13 @@
initial_language_holder = /datum/language_holder/spider
basic_mob_flags = FLAMMABLE_MOB | DEL_ON_DEATH
mob_size = MOB_SIZE_TINY
+ var/menu_description = "Normal spiderling."
unique_name = TRUE
// we have _some_ bite
- melee_damage_lower = 2
- melee_damage_upper = 4
+ melee_damage_lower = 1
+ melee_damage_upper = 2
health = 5 // very low.
maxHealth = 5
@@ -60,7 +61,7 @@
// it's A-OKAY for grow_as to be null for the purposes of this component since we override that behavior anyhow.
AddComponent(\
/datum/component/growth_and_differentiation,\
- growth_time = 10 MINUTES,\
+ growth_time = 1 MINUTES,\
growth_path = grow_as,\
growth_probability = 25,\
lower_growth_value = 1,\
@@ -123,7 +124,7 @@
if(prob(3))
grow_as = pick(/mob/living/basic/giant_spider/tarantula, /mob/living/basic/giant_spider/viper, /mob/living/basic/giant_spider/midwife)
else
- grow_as = pick(/mob/living/basic/giant_spider, /mob/living/basic/giant_spider/hunter, /mob/living/basic/giant_spider/nurse)
+ grow_as = pick(/mob/living/basic/giant_spider, /mob/living/basic/giant_spider/ambush, /mob/living/basic/giant_spider/hunter, /mob/living/basic/giant_spider/scout, /mob/living/basic/giant_spider/nurse, /mob/living/basic/giant_spider/tangle)
var/mob/living/basic/giant_spider/grown = change_mob_type(grow_as, get_turf(src), initial(grow_as.name))
ADD_TRAIT(grown, TRAIT_WAS_EVOLVED, REF(src))
diff --git a/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling_subtypes.dm b/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling_subtypes.dm
index 7b8e8db811d..e969b8f7d2e 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling_subtypes.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling_subtypes.dm
@@ -2,24 +2,95 @@
/// Will differentiate into the base giant spider (known colloquially as the "guard" spider).
/mob/living/basic/spiderling/guard
- grow_as = /mob/living/basic/giant_spider
+ grow_as = /mob/living/basic/giant_spider/guard
+ name = "guard spiderling"
+ desc = "Furry and brown, it looks defenseless. This one has sparkling red eyes."
+ icon_state = "guard_spiderling"
+ icon_dead = "guard_spiderling_dead"
+ menu_description = "Furry and brown, specializing in defense of the hive and other spides."
+
+ /// Will differentiate into the "ambush" giant spider.
+/mob/living/basic/spiderling/ambush
+ grow_as = /mob/living/basic/giant_spider/ambush
+ name = "ambush spiderling"
+ desc = "Furry and white, it looks defenseless. This one has sparkling pink eyes."
+ icon_state = "ambush_spiderling"
+ icon_dead = "ambush_spiderling_dead"
+ menu_description = "Slow spider variant specializing in stalking and ambushing prey, above avarage health and damage with a strong grip."
+
+/// Will differentiate into the "scout" giant spider.
+/mob/living/basic/spiderling/scout
+ grow_as = /mob/living/basic/giant_spider/scout
+ name = "scout spiderling"
+ desc = "Furry and black, it looks defenseless. This one has sparkling purple eyes."
+ icon_state = "scout_spiderling"
+ icon_dead = "scout_spiderling_dead"
+ menu_description = "Fast spider variant specializing in scouting and alerting of prey ,with the ability to travel in vents."
+
/// Will differentiate into the "hunter" giant spider.
/mob/living/basic/spiderling/hunter
grow_as = /mob/living/basic/giant_spider/hunter
+ name = "hunter spiderling"
+ desc = "Furry and black, it looks defenseless. This one has sparkling purple eyes."
+ icon_state = "hunter_spiderling"
+ icon_dead = "hunter_spiderling_dead"
+ menu_description = "Fast spider variant specializing in catching running prey and toxin injection, but has less health and damage."
/// Will differentiate into the "nurse" giant spider.
/mob/living/basic/spiderling/nurse
grow_as = /mob/living/basic/giant_spider/nurse
+ name = "nurse spiderling"
+ desc = "Furry and black, it looks defenseless. This one has sparkling green eyes."
+ icon_state = "nurse_spiderling"
+ icon_dead = "nurse_spiderling_dead"
+ 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."
+
+ /// Will differentiate into the "tangle" giant spider.
+/mob/living/basic/spiderling/tangle
+ grow_as = /mob/living/basic/giant_spider/tangle
+ name = "tangle spiderling"
+ desc = "Furry and brown, it looks defenseless. This one has dim brown eyes."
+ icon_state = "tangle_spiderling"
+ icon_dead = "tangle_spiderling_dead"
+ menu_description = "Support spider variant specializing in contruction to protect their brethren, but has very low amount of health and deals low damage."
/// Will differentiate into the "midwife" giant spider.
/mob/living/basic/spiderling/midwife
grow_as = /mob/living/basic/giant_spider/midwife
+ name = "broodmother spiderling"
+ desc = "Furry and black, it looks defenseless. This one has scintillating green eyes. Might also be hiding a real knife somewhere."
+ icon_state = "midwife_spiderling"
+ icon_dead = "midwife_spiderling_dead"
+ menu_description = "Royal spider variant specializing in reproduction and leadership, but has very low amount of health and deals low damage."
+ gold_core_spawnable = NO_SPAWN
/// Will differentiate into the "viper" giant spider.
/mob/living/basic/spiderling/viper
grow_as = /mob/living/basic/giant_spider/viper
+ name = "viper_spiderling"
+ desc = "Furry and black, it looks defenseless. This one has sparkling purple eyes."
+ icon_state = "viper_spiderling"
+ icon_dead = "viper_spiderling_dead"
+ menu_description = "Extremly Fast spider variant specializing in catching running prey and lethal toxin injection, but has less health and damage."
+ gold_core_spawnable = NO_SPAWN
/// Will differentiate into the "tarantula" giant spider.
/mob/living/basic/spiderling/tarantula
grow_as = /mob/living/basic/giant_spider/tarantula
+ name = "tarantula_spiderling"
+ desc = "Furry and black, it looks defenseless. This one has abyssal red eyes."
+ icon_state = "taratula_spiderling"
+ icon_dead = "tarantula_spiderling_dead"
+ menu_description = "Tank spider variant with an enormous amount of health and damage, but is very slow when not on webbing. It also has a charge ability to close distance with a target after a small windup."
+ gold_core_spawnable = NO_SPAWN
+
+/// Will differentiate into the "hunter" giant spider.
+/mob/living/basic/spiderling/hunter/flesh
+ grow_as = /mob/living/basic/giant_spider/hunter/flesh
+ name = "hunter spiderling"
+ desc = "Furry and black, it looks defenseless. This one has sparkling purple eyes."
+ icon_state = "flesh_spiderling"
+ icon_dead = "flesh_spiderling_dead"
+ menu_description = "Self-sufficient spider variant capable of healing themselves and producing webbbing fast."
+ gold_core_spawnable = NO_SPAWN
diff --git a/code/modules/mob/living/carbon/alien/adult/adult.dm b/code/modules/mob/living/carbon/alien/adult/adult.dm
index 30a9f4c8376..3ddd659b5bd 100644
--- a/code/modules/mob/living/carbon/alien/adult/adult.dm
+++ b/code/modules/mob/living/carbon/alien/adult/adult.dm
@@ -65,7 +65,7 @@ GLOBAL_LIST_INIT(strippable_alien_humanoid_items, create_strippable_list(list(
return FALSE
/mob/living/carbon/alien/adult/check_breath(datum/gas_mixture/breath)
- if(breath?.total_moles() > 0 && !HAS_TRAIT(src, TRAIT_ALIEN_SNEAK))
+ if(breath?.total_moles() > 0 && !HAS_TRAIT(src, TRAIT_SNEAK))
playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, FALSE, -5)
return ..()
diff --git a/code/modules/mob/living/carbon/alien/adult/alien_powers.dm b/code/modules/mob/living/carbon/alien/adult/alien_powers.dm
index f9d6ffc125d..9d3fae5e8fb 100644
--- a/code/modules/mob/living/carbon/alien/adult/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/adult/alien_powers.dm
@@ -338,34 +338,13 @@ Doesn't work on other aliens/AI.*/
new choice_path(owner.loc)
return TRUE
-/datum/action/cooldown/alien/sneak
+/datum/action/cooldown/sneak/alien
name = "Sneak"
+ panel = "Alien"
desc = "Blend into the shadows to stalk your prey."
button_icon_state = "alien_sneak"
- /// The alpha we go to when sneaking.
- var/sneak_alpha = 75
-
-/datum/action/cooldown/alien/sneak/Remove(mob/living/remove_from)
- if(HAS_TRAIT(remove_from, TRAIT_ALIEN_SNEAK))
- remove_from.alpha = initial(remove_from.alpha)
- REMOVE_TRAIT(remove_from, TRAIT_ALIEN_SNEAK, name)
-
- return ..()
-
-/datum/action/cooldown/alien/sneak/Activate(atom/target)
- if(HAS_TRAIT(owner, TRAIT_ALIEN_SNEAK))
- // It's safest to go to the initial alpha of the mob.
- // Otherwise we get permanent invisbility exploits.
- owner.alpha = initial(owner.alpha)
- to_chat(owner, span_noticealien("You reveal yourself!"))
- REMOVE_TRAIT(owner, TRAIT_ALIEN_SNEAK, name)
-
- else
- owner.alpha = sneak_alpha
- to_chat(owner, span_noticealien("You blend into the shadows..."))
- ADD_TRAIT(owner, TRAIT_ALIEN_SNEAK, name)
-
- return TRUE
+ background_icon_state = "bg_alien"
+ overlay_icon_state = "bg_alien_border"
/datum/action/cooldown/alien/regurgitate
name = "Regurgitate"
diff --git a/code/modules/mob/living/carbon/alien/adult/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/adult/caste/sentinel.dm
index e36a6150216..3a6cc5f7b34 100644
--- a/code/modules/mob/living/carbon/alien/adult/caste/sentinel.dm
+++ b/code/modules/mob/living/carbon/alien/adult/caste/sentinel.dm
@@ -6,7 +6,7 @@
icon_state = "aliens"
/mob/living/carbon/alien/adult/sentinel/Initialize(mapload)
- var/datum/action/cooldown/alien/sneak/sneaky_beaky = new(src)
+ var/datum/action/cooldown/sneak/alien/sneaky_beaky = new(src)
sneaky_beaky.Grant(src)
return ..()
diff --git a/code/modules/mob_spawn/ghost_roles/spider_roles.dm b/code/modules/mob_spawn/ghost_roles/spider_roles.dm
index cb84fb351e5..78b570e1381 100644
--- a/code/modules/mob_spawn/ghost_roles/spider_roles.dm
+++ b/code/modules/mob_spawn/ghost_roles/spider_roles.dm
@@ -75,9 +75,12 @@
var/obj/structure/spider/eggcluster/egg
/// The types of spiders that the spawner can produce
var/list/potentialspawns = list(
- /mob/living/basic/giant_spider,
- /mob/living/basic/giant_spider/hunter,
- /mob/living/basic/giant_spider/nurse,
+ /mob/living/basic/spiderling/nurse,
+ /mob/living/basic/spiderling/hunter,
+ /mob/living/basic/spiderling/ambush,
+ /mob/living/basic/spiderling/tangle,
+ /mob/living/basic/spiderling/guard,
+ /mob/living/basic/spiderling/scout,
)
/obj/effect/mob_spawn/ghost_role/spider/Initialize(mapload)
@@ -93,7 +96,7 @@
return ..()
/obj/effect/mob_spawn/ghost_role/spider/process(seconds_per_tick)
- amount_grown += rand(0, 1) * seconds_per_tick
+ amount_grown += rand(5, 15) * seconds_per_tick
if(amount_grown >= 100 && !ready)
ready = TRUE
notify_ghosts("[src] is ready to hatch!", null, enter_link = "(Click to play)", source = src, action = NOTIFY_ORBIT, ignore_key = POLL_IGNORE_SPIDER)
@@ -130,9 +133,9 @@
you_are_text = "You are an enriched spider."
cluster_type = /obj/structure/spider/eggcluster/enriched
potentialspawns = list(
- /mob/living/basic/giant_spider/tarantula,
- /mob/living/basic/giant_spider/viper,
- /mob/living/basic/giant_spider/midwife,
+ /mob/living/basic/spiderling/tarantula,
+ /mob/living/basic/spiderling/viper,
+ /mob/living/basic/spiderling/midwife,
)
/obj/effect/mob_spawn/ghost_role/spider/bloody
@@ -143,7 +146,7 @@
directive = "You are the spawn of a vicious changeling. You have no ambitions except to wreak havoc and ensure your own survival. You are aggressive to all living beings outside of your species, including changelings."
cluster_type = /obj/structure/spider/eggcluster/bloody
potentialspawns = list(
- /mob/living/basic/giant_spider/hunter/flesh,
+ /mob/living/basic/spiderling/hunter/flesh,
)
/obj/effect/mob_spawn/ghost_role/spider/midwife
@@ -153,7 +156,7 @@
directive = "Ensure the survival of the spider species and overtake whatever structure you find yourself in."
cluster_type = /obj/structure/spider/eggcluster/midwife
potentialspawns = list(
- /mob/living/basic/giant_spider/midwife,
+ /mob/living/basic/spiderling/midwife,
)
/**
@@ -169,8 +172,9 @@
var/list/spider_list = list()
var/list/display_spiders = list()
for(var/choice in potentialspawns)
- var/mob/living/basic/giant_spider/spider = choice
- spider_list[initial(spider.name)] = choice
+ var/mob/living/basic/spiderling/chosen_spiderling = choice
+ var/mob/living/basic/giant_spider/spider = initial(chosen_spiderling.grow_as)
+ spider_list[initial(spider.name)] = chosen_spiderling
var/datum/radial_menu_choice/option = new
option.image = image(icon = initial(spider.icon), icon_state = initial(spider.icon_state))
@@ -190,5 +194,5 @@
if(QDELETED(src) || QDELETED(user) || !chosen_spider)
return FALSE
mob_type = chosen_spider
- mob_name = "[mob_name] ([rand(1, 1000)])"
+ mob_name = "spiderling"
return ..()
diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm
index 48422805d57..6267de09a02 100644
--- a/code/modules/movespeed/modifiers/mobs.dm
+++ b/code/modules/movespeed/modifiers/mobs.dm
@@ -97,11 +97,14 @@
variable = TRUE
flags = IGNORE_NOSLOW
-/datum/movespeed_modifier/tarantula_web
- multiplicative_slowdown = 5
+/datum/movespeed_modifier/fast_web
+ multiplicative_slowdown = 0.2
-/datum/movespeed_modifier/duct_spider_web
- multiplicative_slowdown = 1
+/datum/movespeed_modifier/average_web
+ multiplicative_slowdown = 1.2
+
+/datum/movespeed_modifier/slow_web
+ multiplicative_slowdown = 5
/datum/movespeed_modifier/gravity
blacklisted_movetypes = FLOATING
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 57f1d4bcb5c..365d7576b6e 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/actions/actions_animal.dmi b/icons/mob/actions/actions_animal.dmi
index 1551a785275..1fcda97922c 100644
Binary files a/icons/mob/actions/actions_animal.dmi and b/icons/mob/actions/actions_animal.dmi differ
diff --git a/icons/mob/actions/actions_xeno.dmi b/icons/mob/actions/actions_xeno.dmi
index 79823bb575c..32e70ee3a3a 100644
Binary files a/icons/mob/actions/actions_xeno.dmi and b/icons/mob/actions/actions_xeno.dmi differ
diff --git a/icons/mob/simple/animal.dmi b/icons/mob/simple/animal.dmi
index 71a1b944a74..edc6d9ccaf1 100644
Binary files a/icons/mob/simple/animal.dmi and b/icons/mob/simple/animal.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index e1870c32cfd..b6ba8e7771d 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -739,6 +739,7 @@
#include "code\datums\actions\mobs\projectileattack.dm"
#include "code\datums\actions\mobs\sign_language.dm"
#include "code\datums\actions\mobs\small_sprite.dm"
+#include "code\datums\actions\mobs\sneak.dm"
#include "code\datums\actions\mobs\transform_weapon.dm"
#include "code\datums\actions\mobs\sequences\dash_attack.dm"
#include "code\datums\actions\mobs\sequences\projectile.dm"
@@ -3986,6 +3987,7 @@
#include "code\modules\mob\living\basic\space_fauna\spider\spider_abilities\hivemind.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\spider_abilities\lay_eggs.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\spider_abilities\web.dm"
+#include "code\modules\mob\living\basic\space_fauna\spider\spider_abilities\web_sneak.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\spider_abilities\wrap.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\spiderlings\spiderling.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\spiderlings\spiderling_subtypes.dm"
diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss
index b32181b8e13..9e7b190f99c 100644
--- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss
+++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss
@@ -668,12 +668,18 @@ em {
font-weight: bold;
}
-.spider {
+.spiderbroodmother {
color: #8800ff;
font-weight: bold;
font-size: 185%;
}
+.spiderscout {
+ color: #231d99;
+ font-weight: bold;
+ font-size: 120%;
+}
+
.interface {
color: #750e75;
}
diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss
index 44fbdc37411..c55ba0a060b 100644
--- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss
+++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss
@@ -700,12 +700,18 @@ h2.alert {
font-weight: bold;
}
-.spider {
+.spiderbroodmother {
color: #4d004d;
font-weight: bold;
font-size: 185%;
}
+.spiderscout {
+ color: #1b10cd;
+ font-weight: bold;
+ font-size: 120%;
+}
+
.interface {
color: #330033;
}