diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index a172ea8874c..c98b60bf9aa 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -173,7 +173,7 @@ /datum/mood_event/hope_lavaland description = "What a peculiar emblem. It makes me feel hopeful for my future.\n" - mood_change = 5 + mood_change = 10 /datum/mood_event/nanite_happiness description = "+++++++HAPPINESS ENHANCEMENT+++++++\n" diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 960eb74dd78..1d5762d523b 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -759,6 +759,8 @@ user.changeNext_move(CLICK_CD_MELEE * 0.5) //when closed, it attacks very rapidly /obj/item/melee/transforming/cleaving_saw/nemesis_effects(mob/living/user, mob/living/target) + if(istype(target, /mob/living/simple_animal/hostile/asteroid/elite)) + return var/datum/status_effect/stacking/saw_bleed/B = target.has_status_effect(STATUS_EFFECT_SAWBLEED) if(!B) target.apply_status_effect(STATUS_EFFECT_SAWBLEED,bleed_stacks_per_hit) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm index ecb8fceeaf1..16a1480e8ec 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm @@ -11,10 +11,10 @@ robust_searching = TRUE ranged_ignores_vision = TRUE ranged = TRUE - obj_damage = 5 + obj_damage = 30 vision_range = 6 aggro_vision_range = 18 - environment_smash = ENVIRONMENT_SMASH_NONE //This is to prevent elites smashing up the mining station, we'll make sure they can smash minerals fine below. + environment_smash = ENVIRONMENT_SMASH_NONE //This is to prevent elites smashing up the mining station (entirely), we'll make sure they can smash minerals fine below. harm_intent_damage = 0 //Punching elites gets you nowhere stat_attack = UNCONSCIOUS layer = LARGE_MOB_LAYER @@ -41,7 +41,7 @@ var/obj/structure/elite_tumor/T = target if(T.mychild == src && T.activity == TUMOR_PASSIVE) var/elite_remove = alert("Re-enter the tumor?", "Despawn yourself?", "Yes", "No") - if(elite_remove == "No" || !src || QDELETED(src)) + if(elite_remove == "No" || QDELETED(src) || !Adjacent(T)) return T.mychild = null T.activity = TUMOR_INACTIVE @@ -52,6 +52,9 @@ if(ismineralturf(target)) var/turf/closed/mineral/M = target M.gets_drilled() + if(istype(target, /obj/mecha)) + var/obj/mecha/M = target + M.take_damage(50, BRUTE, "melee", 1) //Elites can't talk (normally)! /mob/living/simple_animal/hostile/asteroid/elite/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) @@ -185,8 +188,6 @@ While using this makes the system rely on OnFire, it still gives options for tim . = ..() if(istype(I, /obj/item/organ/regenerative_core) && activity == TUMOR_INACTIVE && !boosted) var/obj/item/organ/regenerative_core/core = I - if(!core.preserved) - return visible_message("As [user] drops the core into [src], [src] appears to swell.") icon_state = "advanced_tumor" boosted = TRUE @@ -256,7 +257,7 @@ While using this makes the system rely on OnFire, it still gives options for tim mychild.revive(full_heal = TRUE, admin_revive = TRUE) if(boosted) times_won++ - mychild.maxHealth = mychild.maxHealth * 0.5 + mychild.maxHealth = mychild.maxHealth * 0.4 mychild.health = mychild.maxHealth if(times_won == 1) mychild.playsound_local(get_turf(mychild), 'sound/effects/magic.ogg', 40, 0) @@ -284,13 +285,13 @@ While using this makes the system rely on OnFire, it still gives options for tim if(E.stat != DEAD || E.sentience_type != SENTIENCE_BOSS || !E.key) user.visible_message("It appears [E] is unable to be revived right now. Perhaps try again later.") return - E.faction = list("neutral") + E.faction = list("[REF(user)]") E.revive(full_heal = TRUE, admin_revive = TRUE) user.visible_message("[user] stabs [E] with [src], reviving it.") E.playsound_local(get_turf(E), 'sound/effects/magic.ogg', 40, 0) to_chat(E, "You have been revived by [user]. While you can't speak to them, you owe [user] a great debt. Assist [user.p_them()] in achieving [user.p_their()] goals, regardless of risk.Note that you now share the loyalties of [user]. You are expected not to intentionally sabotage their faction unless commanded to!") - E.maxHealth = E.maxHealth * 0.5 + E.maxHealth = E.maxHealth * 0.4 E.health = E.maxHealth E.desc = "[E.desc] However, this one appears appears less wild in nature, and calmer around people." E.sentience_type = SENTIENCE_ORGANIC diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm index d085204bc1f..ac9b00cab08 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm @@ -26,8 +26,8 @@ icon_dead = "egg_sac" icon_gib = "syndicate_gib" health_doll_icon = "broodmother" - maxHealth = 800 - health = 800 + maxHealth = 1000 + health = 1000 melee_damage_lower = 30 melee_damage_upper = 30 armour_penetration = 30 @@ -232,11 +232,13 @@ // Broodmother's loot: Broodmother Tongue /obj/item/crusher_trophy/broodmother_tongue name = "broodmother tongue" - desc = "The tongue of a broodmother. If attached a certain way, makes for a suitable crusher trophy." + desc = "The tongue of a broodmother. If attached a certain way, makes for a suitable crusher trophy. It also feels very spongey, I wonder what would happen if you squeezed it?..." icon = 'icons/obj/lavaland/elite_trophies.dmi' icon_state = "broodmother_tongue" denied_type = /obj/item/crusher_trophy/broodmother_tongue bonus_value = 10 + /// Time at which the item becomes usable again + var/use_time /obj/item/crusher_trophy/broodmother_tongue/effect_desc() return "mark detonation to have a [bonus_value]% chance to summon a patch of goliath tentacles at the target's location" @@ -244,3 +246,21 @@ /obj/item/crusher_trophy/broodmother_tongue/on_mark_detonation(mob/living/target, mob/living/user) if(rand(1, 100) <= bonus_value && target.stat != DEAD) new /obj/effect/temp_visual/goliath_tentacle/broodmother/patch(get_turf(target), user) + +/obj/item/crusher_trophy/broodmother_tongue/attack_self(mob/user) + if(!isliving(user)) + return + var/mob/living/living_user = user + if(use_time > world.time) + to_chat(living_user, "The tongue looks dried out. You'll need to wait longer to use it again.") + return + else if("lava" in living_user.weather_immunities) + to_chat(living_user, "You stare at the tongue. You don't think this is any use to you.") + return + living_user.weather_immunities |= "lava" + to_chat(living_user, "You squeeze the tongue, and some transluscent liquid shoots out all over you.") + addtimer(CALLBACK(src, .proc/remove_lavaproofing, living_user), 10 SECONDS) + use_time = world.time + 60 SECONDS + +/obj/item/crusher_trophy/broodmother_tongue/proc/remove_lavaproofing(mob/living/user) + user.weather_immunities -= "lava" diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm index 541b78e638f..b40587da0c2 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm @@ -25,8 +25,8 @@ icon_dead = "herald_dying" icon_gib = "syndicate_gib" health_doll_icon = "herald" - maxHealth = 800 - health = 800 + maxHealth = 1000 + health = 1000 melee_damage_lower = 20 melee_damage_upper = 20 attack_verb_continuous = "preaches to" @@ -123,7 +123,7 @@ if(HERALD_MIRROR) herald_mirror() -/mob/living/simple_animal/hostile/asteroid/elite/herald/proc/shoot_projectile(turf/marker, set_angle, var/is_teleshot) +/mob/living/simple_animal/hostile/asteroid/elite/herald/proc/shoot_projectile(turf/marker, set_angle, var/is_teleshot, var/is_trishot) var/turf/startloc = get_turf(src) var/obj/projectile/herald/H = null if(!is_teleshot) @@ -135,25 +135,28 @@ if(target) H.original = target H.fire(set_angle) + if(is_trishot) + shoot_projectile(marker, set_angle + 15, FALSE, FALSE) + shoot_projectile(marker, set_angle - 15, FALSE, FALSE) /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_trishot(target) ranged_cooldown = world.time + 30 playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) var/target_turf = get_turf(target) var/angle_to_target = Get_Angle(src, target_turf) - shoot_projectile(target_turf, angle_to_target, FALSE) - addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE), 2) - addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE), 4) + shoot_projectile(target_turf, angle_to_target, FALSE, TRUE) + addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE, TRUE), 2) + addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE, TRUE), 4) if(health < maxHealth * 0.5) playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) - addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE), 10) - addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE), 12) - addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE), 14) + addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE, TRUE), 10) + addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE, TRUE), 12) + addtimer(CALLBACK(src, .proc/shoot_projectile, target_turf, angle_to_target, FALSE, TRUE), 14) -/mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_circleshot() +/mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_circleshot(offset) var/static/list/directional_shot_angles = list(0, 45, 90, 135, 180, 225, 270, 315) for(var/i in directional_shot_angles) - shoot_projectile(get_turf(src), i, FALSE) + shoot_projectile(get_turf(src), i + offset, FALSE, FALSE) /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/unenrage() if(stat == DEAD || is_mirror) @@ -165,10 +168,10 @@ if(!is_mirror) icon_state = "herald_enraged" playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) - addtimer(CALLBACK(src, .proc/herald_circleshot), 5) + addtimer(CALLBACK(src, .proc/herald_circleshot, 0), 5) if(health < maxHealth * 0.5) playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) - addtimer(CALLBACK(src, .proc/herald_circleshot), 15) + addtimer(CALLBACK(src, .proc/herald_circleshot, 22.5), 15) addtimer(CALLBACK(src, .proc/unenrage), 20) /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_teleshot(target) @@ -176,7 +179,7 @@ playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) var/target_turf = get_turf(target) var/angle_to_target = Get_Angle(src, target_turf) - shoot_projectile(target_turf, angle_to_target, TRUE) + shoot_projectile(target_turf, angle_to_target, TRUE, FALSE) /mob/living/simple_animal/hostile/asteroid/elite/herald/proc/herald_mirror() ranged_cooldown = world.time + 40 @@ -250,7 +253,7 @@ icon = 'icons/obj/lavaland/elite_trophies.dmi' icon_state = "herald_cloak" body_parts_covered = CHEST|GROIN|ARMS - hit_reaction_chance = 10 + hit_reaction_chance = 20 /obj/item/clothing/neck/cloak/herald_cloak/proc/reactionshot(mob/living/carbon/owner) var/static/list/directional_shot_angles = list(0, 45, 90, 135, 180, 225, 270, 315) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm index 19674971b29..6269db8d1fd 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm @@ -25,8 +25,8 @@ icon_dead = "legionnaire_dead" icon_gib = "syndicate_gib" health_doll_icon = "legionnaire" - maxHealth = 800 - health = 800 + maxHealth = 1000 + health = 1000 melee_damage_lower = 30 melee_damage_upper = 30 attack_verb_continuous = "slashes its arms at" @@ -48,6 +48,8 @@ var/mob/living/simple_animal/hostile/asteroid/elite/legionnairehead/myhead = null var/obj/structure/legionnaire_bonfire/mypile = null var/has_head = TRUE + /// Whether or not the legionnaire is currently charging, used to deny movement input if he is + var/charging = FALSE /datum/action/innate/elite_attack/legionnaire_charge name = "Legionnaire Charge" @@ -95,31 +97,51 @@ bonfire_teleport() if(SPEW_SMOKE) spew_smoke() + +/mob/living/simple_animal/hostile/asteroid/elite/legionnaire/Move() + if(charging) + return FALSE + return ..() +/mob/living/simple_animal/hostile/asteroid/elite/legionnaire/MiddleClickOn(atom/A) + . = ..() + if(!myhead) + return + var/turf/T = get_turf(A) + if(T) + myhead.LoseTarget() + myhead.Goto(T, myhead.move_to_delay) + /mob/living/simple_animal/hostile/asteroid/elite/legionnaire/proc/legionnaire_charge(target) - ranged_cooldown = world.time + 50 + ranged_cooldown = world.time + 3.5 SECONDS + charging = TRUE var/dir_to_target = get_dir(get_turf(src), get_turf(target)) var/turf/T = get_step(get_turf(src), dir_to_target) - for(var/i in 1 to 4) + for(var/i in 1 to 6) new /obj/effect/temp_visual/dragon_swoop/legionnaire(T) T = get_step(T, dir_to_target) playsound(src,'sound/magic/demon_attack1.ogg', 200, 1) visible_message("[src] prepares to charge!") - addtimer(CALLBACK(src, .proc/legionnaire_charge_2, dir_to_target, 0), 5) + addtimer(CALLBACK(src, .proc/legionnaire_charge_2, dir_to_target, 0), 4) /mob/living/simple_animal/hostile/asteroid/elite/legionnaire/proc/legionnaire_charge_2(var/move_dir, var/times_ran) - if(times_ran >= 4) + if(times_ran >= 6) + charging = FALSE return var/turf/T = get_step(get_turf(src), move_dir) if(ismineralturf(T)) var/turf/closed/mineral/M = T M.gets_drilled() if(T.density) + charging = FALSE return for(var/obj/structure/window/W in T.contents) + charging = FALSE return for(var/obj/machinery/door/D in T.contents) - return + if(D.density) + charging = FALSE + return forceMove(T) playsound(src,'sound/effects/bang.ogg', 200, 1) var/list/hit_things = list() @@ -128,12 +150,12 @@ if(faction_check_mob(L)) return hit_things += L - visible_message("[src] attacks [L] with much force!") - to_chat(L, "[src] grabs you and throws you with much force!") + visible_message("[src] tramples and kicks [L]!") + to_chat(L, "[src] tramples you and kicks you away!") L.safe_throw_at(throwtarget, 10, 1, src) L.Paralyze(20) L.adjustBruteLoss(50) - addtimer(CALLBACK(src, .proc/legionnaire_charge_2, move_dir, (times_ran + 1)), 2) + addtimer(CALLBACK(src, .proc/legionnaire_charge_2, move_dir, (times_ran + 1)), 1.5) /mob/living/simple_animal/hostile/asteroid/elite/legionnaire/proc/head_detach(target) ranged_cooldown = world.time + 10 @@ -147,17 +169,16 @@ icon_aggro = "legionnaire_headless" visible_message("[src]'s head flies off!") var/mob/living/simple_animal/hostile/asteroid/elite/legionnairehead/newhead = new /mob/living/simple_animal/hostile/asteroid/elite/legionnairehead(loc) - newhead.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) newhead.GiveTarget(target) newhead.faction = faction.Copy() myhead = newhead myhead.body = src if(health < maxHealth * 0.25) + myhead.melee_damage_lower = 40 + myhead.melee_damage_upper = 40 + else if(health < maxHealth * 0.5) myhead.melee_damage_lower = 30 myhead.melee_damage_upper = 30 - else if(health < maxHealth * 0.5) - myhead.melee_damage_lower = 20 - myhead.melee_damage_upper = 20 /mob/living/simple_animal/hostile/asteroid/elite/legionnaire/proc/onHeadDeath() myhead = null @@ -221,10 +242,10 @@ icon_aggro = "legionnaire_head" icon_dead = "legionnaire_dead" icon_gib = "syndicate_gib" - maxHealth = 80 - health = 80 - melee_damage_lower = 10 - melee_damage_upper = 10 + maxHealth = 200 + health = 200 + melee_damage_lower = 20 + melee_damage_upper = 20 attack_verb_continuous = "bites at" attack_verb_simple = "bite at" attack_sound = 'sound/effects/curse1.ogg' @@ -282,11 +303,13 @@ /obj/item/crusher_trophy/legionnaire_spine name = "legionnaire spine" - desc = "The spine of a legionnaire. It almost feels like it's moving..." + desc = "The spine of a legionnaire. With some creativity, you could use it as a crusher trophy. Alternatively, shaking it might do something as well." icon = 'icons/obj/lavaland/elite_trophies.dmi' icon_state = "legionnaire_spine" denied_type = /obj/item/crusher_trophy/legionnaire_spine bonus_value = 20 + /// Time at which the item becomes usable again + var/next_use_time /obj/item/crusher_trophy/legionnaire_spine/effect_desc() return "mark detonation to have a [bonus_value]% chance to summon a loyal legion skull" @@ -295,7 +318,20 @@ if(!rand(1, 100) <= bonus_value || target.stat == DEAD) return var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion(user.loc) - A.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) A.GiveTarget(target) - A.friends = user + A.friends += user A.faction = user.faction.Copy() + +/obj/item/crusher_trophy/legionnaire_spine/attack_self(mob/user) + if(!isliving(user)) + return + var/mob/living/LivingUser = user + if(next_use_time > world.time) + LivingUser.visible_message("[LivingUser] shakes the [src], but nothing happens...") + to_chat(LivingUser, "You need to wait longer to use this again.") + return + LivingUser.visible_message("[LivingUser] shakes the [src] and summons a legion skull!") + var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/LegionSkull = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion(LivingUser.loc) + LegionSkull.friends += LivingUser + LegionSkull.faction = LivingUser.faction.Copy() + next_use_time = world.time + 4 SECONDS diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm index 511362d1236..ef1bb17345d 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm @@ -25,8 +25,8 @@ icon_dead = "pandora_dead" icon_gib = "syndicate_gib" health_doll_icon = "pandora" - maxHealth = 800 - health = 800 + maxHealth = 1000 + health = 1000 melee_damage_lower = 15 melee_damage_upper = 15 attack_verb_continuous = "smashes into the side of" @@ -128,7 +128,7 @@ new /obj/effect/temp_visual/hierophant/blast/pandora(t, src) /mob/living/simple_animal/hostile/asteroid/elite/pandora/proc/pandora_teleport(target) - ranged_cooldown = world.time + cooldown_time + ranged_cooldown = world.time + (cooldown_time * 2) var/turf/T = get_turf(target) var/turf/source = get_turf(src) new /obj/effect/temp_visual/hierophant/telegraph(T, src)