diff --git a/beestation.dme b/beestation.dme index c1184eb49f1..2cfa998e5d9 100644 --- a/beestation.dme +++ b/beestation.dme @@ -3187,6 +3187,7 @@ #include "code\modules\spells\spell_types\blind.dm" #include "code\modules\spells\spell_types\bloodcrawl.dm" #include "code\modules\spells\spell_types\charge.dm" +#include "code\modules\spells\spell_types\cone_spells.dm" #include "code\modules\spells\spell_types\conjure.dm" #include "code\modules\spells\spell_types\construct_spells.dm" #include "code\modules\spells\spell_types\curse.dm" diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 0ec5f605ca7..66b5607f2e7 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -101,6 +101,14 @@ #define STATUS_EFFECT_IPC_EMP /datum/status_effect/ipc/emp //EMP'd IPC +<<<<<<< HEAD +======= +#define STATUS_EFFECT_SLIMEGRUB /datum/status_effect/slimegrub //infected slime + +#define STATUS_EFFECT_AMOK /datum/status_effect/amok //Makes the target automatically strike out at adjecent non-heretics. + +#define STATUS_EFFECT_CLOUDSTRUCK /datum/status_effect/cloudstruck //blinds and applies an overlay. +>>>>>>> 11a361a3c0... [TG PORT] Replaces rust wave with entropic plume (#7489) //---------// // NEUTRAL // //---------// diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index de71c4b4eb8..dcc8566ec85 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -944,3 +944,114 @@ name = "Electro-Magnetic Pulse" desc = "You've been hit with an EMP! You're malfunctioning!" icon_state = "hypnosis" +<<<<<<< HEAD +======= + +/datum/status_effect/slimegrub + id = "grub_infection" + duration = 60 SECONDS //a redgrub infestation in a slime + status_type = STATUS_EFFECT_UNIQUE + tick_interval = 1 + alert_type = /atom/movable/screen/alert/status_effect/grub + var/adult = FALSE + var/spawnbonus = 0 + var/deathcounter = 300 + var/list/diseases = list() + +/datum/status_effect/slimegrub/on_apply(mob/living/new_owner, ...) + . = ..() + if(isslime(new_owner)) + var/mob/living/simple_animal/slime/S = new_owner + if(S.is_adult) + adult = TRUE + duration = world.time + 120 SECONDS + if(S.amount_grown >= 9) + S.amount_grown = 8 //can't split or evolve + deathcounter = (300 + (300 * adult)) + +/datum/status_effect/slimegrub/tick() + if(isslime(owner)) + var/mob/living/simple_animal/slime/S = owner + if(S.amount_grown >= 9) + S.amount_grown = 8 + if((S.reagents.has_reagent(/datum/reagent/consumable/capsaicin) || S.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)) //redgrubs don't like heat. heating them up for too long kills them + if(prob(10)) + qdel(src) + else //don't tick while being cured + deathcounter -= 2 + if(deathcounter <= 0) + var/spawns = rand(1, 3 + (adult * 3)) + for(var/I in 1 to (spawns + spawnbonus)) + var/mob/living/simple_animal/hostile/redgrub/grub = new(S.loc) + grub.grubdisease = diseases + grub.food += 15 + playsound(S, 'sound/effects/attackblob.ogg', 60, 1) + S.visible_message("[S] is eaten from the inside by [spawns] red grubs, leaving no trace!") + S.gib() + else + qdel(src)//no effect on nonslimes + +/atom/movable/screen/alert/status_effect/grub + name = "Infected" + desc = "You have a redgrub infection, and can't reproduce or grow! If you don't find a source of heat, you will die!" + icon_state = "grub" + +/datum/status_effect/amok + id = "amok" + status_type = STATUS_EFFECT_REPLACE + alert_type = null + duration = 10 SECONDS + tick_interval = 1 SECONDS + +/datum/status_effect/amok/on_apply(mob/living/afflicted) + . = ..() + to_chat(owner, "You feel filled with a rage that is not your own!") + +/datum/status_effect/amok/tick() + . = ..() + var/prev_intent = owner.a_intent + owner.a_intent = INTENT_HARM + + var/list/mob/living/targets = list() + for(var/mob/living/potential_target in oview(owner, 1)) + if(IS_HERETIC(potential_target) || potential_target.mind?.has_antag_datum(/datum/antagonist/heretic_monster)) + continue + targets += potential_target + if(LAZYLEN(targets)) + owner.log_message(" attacked someone due to the amok debuff.", LOG_ATTACK) //the following attack will log itself + owner.ClickOn(pick(targets)) + owner.a_intent = prev_intent + +/datum/status_effect/cloudstruck + id = "cloudstruck" + status_type = STATUS_EFFECT_REPLACE + duration = 3 SECONDS + on_remove_on_mob_delete = TRUE + ///This overlay is applied to the owner for the duration of the effect. + var/mutable_appearance/mob_overlay + +/datum/status_effect/cloudstruck/on_creation(mob/living/new_owner, set_duration) + if(isnum(set_duration)) + duration = set_duration + . = ..() + +/datum/status_effect/cloudstruck/on_apply() + mob_overlay = mutable_appearance('icons/effects/eldritch.dmi', "cloud_swirl", ABOVE_MOB_LAYER) + owner.overlays += mob_overlay + owner.update_icon() + ADD_TRAIT(owner, TRAIT_BLIND, "cloudstruck") + return TRUE + +/datum/status_effect/cloudstruck/on_remove() + . = ..() + if(QDELETED(owner)) + return + REMOVE_TRAIT(owner, TRAIT_BLIND, "cloudstruck") + if(owner) + owner.overlays -= mob_overlay + owner.update_icon() + +/datum/status_effect/cloudstruck/Destroy() + . = ..() + QDEL_NULL(mob_overlay) +>>>>>>> 11a361a3c0... [TG PORT] Replaces rust wave with entropic plume (#7489) diff --git a/code/game/turfs/closed/wall/reinf_walls.dm b/code/game/turfs/closed/wall/reinf_walls.dm index 78dd5e0c1a8..3a60ca1b99c 100644 --- a/code/game/turfs/closed/wall/reinf_walls.dm +++ b/code/game/turfs/closed/wall/reinf_walls.dm @@ -229,9 +229,18 @@ /turf/closed/wall/r_wall/rust_heretic_act() if(prob(50)) return +<<<<<<< HEAD if(prob(70)) new /obj/effect/temp_visual/glowing_rune(src) ChangeTurf(/turf/closed/wall/r_wall/rust) +======= + if(HAS_TRAIT(src, TRAIT_RUSTY)) + ScrapeAway() + return + if(prob(70)) + new /obj/effect/temp_visual/glowing_rune(src) + return ..() +>>>>>>> 11a361a3c0... [TG PORT] Replaces rust wave with entropic plume (#7489) /turf/closed/wall/r_wall/syndicate name = "hull" diff --git a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm index 71184b81699..6a006932e53 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm @@ -461,7 +461,7 @@ desc = "Gives AOE spell that causes heavy bleeding and blood loss." cost = 1 spell_to_add = /obj/effect/proc_holder/spell/pointed/cleave - next_knowledge = list(/datum/eldritch_knowledge/spell/rust_wave,/datum/eldritch_knowledge/spell/flame_birth) + next_knowledge = list(/datum/eldritch_knowledge/spell/entropic_plume,/datum/eldritch_knowledge/spell/flame_birth) /datum/eldritch_knowledge/spell/blood_siphon name = "Blood Siphon" @@ -480,7 +480,7 @@ cost = 1 required_atoms = list(/obj/effect/decal/cleanable/ash,/obj/item/bodypart/head,/obj/item/book) mob_to_summon = /mob/living/simple_animal/hostile/eldritch/ash_spirit - next_knowledge = list(/datum/eldritch_knowledge/summon/stalker,/datum/eldritch_knowledge/spell/rust_wave) + next_knowledge = list(/datum/eldritch_knowledge/summon/stalker,/datum/eldritch_knowledge/spell/flame_birth) /datum/eldritch_knowledge/summon/rusty name = "Rusted Ritual" @@ -489,4 +489,4 @@ cost = 1 required_atoms = list(/obj/effect/decal/cleanable/vomit,/obj/item/bodypart/head,/obj/item/book) mob_to_summon = /mob/living/simple_animal/hostile/eldritch/rust_spirit - next_knowledge = list(/datum/eldritch_knowledge/summon/stalker,/datum/eldritch_knowledge/spell/flame_birth) + next_knowledge = list(/datum/eldritch_knowledge/summon/stalker,/datum/eldritch_knowledge/spell/entropic_plume) diff --git a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm index 2a0f54f6af7..e2f5a01e077 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm @@ -631,3 +631,75 @@ range = 10 invocation = "E'E'S" action_background_icon_state = "bg_ecult" + +/obj/effect/temp_visual/dir_setting/entropic + icon = 'icons/effects/160x160.dmi' + icon_state = "entropic_plume" + duration = 3 SECONDS + +/obj/effect/temp_visual/dir_setting/entropic/setDir(dir) + . = ..() + switch(dir) + if(NORTH) + pixel_x = -64 + if(SOUTH) + pixel_x = -64 + pixel_y = -128 + if(EAST) + pixel_y = -64 + if(WEST) + pixel_y = -64 + pixel_x = -128 + +/obj/effect/temp_visual/glowing_rune + icon = 'icons/effects/eldritch.dmi' + icon_state = "small_rune_1" + duration = 1 MINUTES + layer = LOW_SIGIL_LAYER + +/obj/effect/temp_visual/glowing_rune/Initialize() + . = ..() + pixel_y = rand(-6,6) + pixel_x = rand(-6,6) + icon_state = "small_rune_[rand(12)]" + update_icon() + +/obj/effect/proc_holder/spell/cone/staggered/entropic_plume + name = "Entropic Plume" + desc = "Spews forth a disorienting plume that causes enemies to strike each other, briefly blinds them(increasing with range) and poisons them(decreasing with range). Also spreads rust in the path of the plume." + school = "illusion" + invocation = "'NTR'P'C PL'M'" + invocation_type = INVOCATION_WHISPER + clothes_req = FALSE + action_background_icon_state = "bg_ecult" + action_icon = 'icons/mob/actions/actions_ecult.dmi' + action_icon_state = "entropic_plume" + charge_max = 300 + cone_levels = 5 + respect_density = TRUE + +/obj/effect/proc_holder/spell/cone/staggered/entropic_plume/cast(list/targets,mob/user = usr) + . = ..() + new /obj/effect/temp_visual/dir_setting/entropic(get_step(user,user.dir), user.dir) + +/obj/effect/proc_holder/spell/cone/staggered/entropic_plume/do_turf_cone_effect(turf/target_turf, level) + . = ..() + target_turf.rust_heretic_act() + +/obj/effect/proc_holder/spell/cone/staggered/entropic_plume/do_mob_cone_effect(mob/living/victim, level) + . = ..() + if(victim.anti_magic_check() || IS_HERETIC(victim) || victim.mind?.has_antag_datum(/datum/antagonist/heretic_monster)) + return + victim.apply_status_effect(STATUS_EFFECT_AMOK) + victim.apply_status_effect(STATUS_EFFECT_CLOUDSTRUCK, (level*10)) + if(iscarbon(victim)) + var/mob/living/carbon/carbon_victim = victim + carbon_victim.reagents.add_reagent(/datum/reagent/eldritch, min(1, 6-level)) + +/obj/effect/proc_holder/spell/cone/staggered/entropic_plume/calculate_cone_shape(current_level) + if(current_level == cone_levels) + return 5 + else if(current_level == cone_levels-1) + return 3 + else + return 2 diff --git a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm index 7f079ca7e44..d78778ddcc9 100644 --- a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm +++ b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm @@ -83,7 +83,7 @@ gain_text = "The Blade will guide you through the flesh, should you let it." desc = "Your blade of choice will now transfer your pain as toxic damage." cost = 2 - next_knowledge = list(/datum/eldritch_knowledge/spell/rust_wave) + next_knowledge = list(/datum/eldritch_knowledge/spell/entropic_plume) banned_knowledge = list(/datum/eldritch_knowledge/ash_blade_upgrade,/datum/eldritch_knowledge/flesh_blade_upgrade) route = PATH_RUST @@ -94,12 +94,12 @@ if(istype(carbon_user) && istype(carbon_target)) carbon_target.adjustToxLoss((carbon_user.maxHealth - carbon_user.health)/10) -/datum/eldritch_knowledge/spell/rust_wave - name = "Wave of Rust" - desc = "You can now send a projectile that converts an area into rust." +/datum/eldritch_knowledge/spell/entropic_plume + name = "Entropic Plume" + desc = "You can now send a befuddling plume that blinds, poisons and makes enemies strike each other. Also converts the area into rust." gain_text = "Messenger's of hope fear the rustbringer!" cost = 1 - spell_to_add = /obj/effect/proc_holder/spell/targeted/projectile/dumbfire/rust_wave + spell_to_add = /obj/effect/proc_holder/spell/cone/staggered/entropic_plume next_knowledge = list(/datum/eldritch_knowledge/final/rust_final,/datum/eldritch_knowledge/spell/cleave,/datum/eldritch_knowledge/summon/rusty) route = PATH_RUST diff --git a/code/modules/spells/spell_types/cone_spells.dm b/code/modules/spells/spell_types/cone_spells.dm new file mode 100644 index 00000000000..63bae4b7cf1 --- /dev/null +++ b/code/modules/spells/spell_types/cone_spells.dm @@ -0,0 +1,117 @@ +/obj/effect/proc_holder/spell/cone + name = "Cone of Nothing" + desc = "Does nothing in a cone! Wow!" + school = "evocation" + charge_max = 100 + clothes_req = FALSE + invocation = "FUKAN NOTHAN" + invocation_type = "shout" + sound = 'sound/magic/forcewall.ogg' + action_icon_state = "shield" + range = -1 + cooldown_min = 0.5 SECONDS + ///This controls how many levels the cone has, increase this value to make a bigger cone. + var/cone_levels = 3 + ///This value determines if the cone penetrates walls. + var/respect_density = FALSE + +/obj/effect/proc_holder/spell/cone/choose_targets(mob/user = usr) + perform(null, user=user) + +///This proc creates a list of turfs that are hit by the cone +/obj/effect/proc_holder/spell/cone/proc/cone_helper(var/turf/starter_turf, var/dir_to_use, var/cone_levels = 3) + var/list/turfs_to_return = list() + var/turf/turf_to_use = starter_turf + var/turf/left_turf + var/turf/right_turf + var/right_dir + var/left_dir + switch(dir_to_use) + if(NORTH) + left_dir = WEST + right_dir = EAST + if(SOUTH) + left_dir = EAST + right_dir = WEST + if(EAST) + left_dir = NORTH + right_dir = SOUTH + if(WEST) + left_dir = SOUTH + right_dir = NORTH + + + for(var/i in 1 to cone_levels) + var/list/level_turfs = list() + turf_to_use = get_step(turf_to_use, dir_to_use) + level_turfs += turf_to_use + if(i != 1) + left_turf = get_step(turf_to_use, left_dir) + level_turfs += left_turf + right_turf = get_step(turf_to_use, right_dir) + level_turfs += right_turf + for(var/left_i in 1 to i -calculate_cone_shape(i)) + if(left_turf.density && respect_density) + break + left_turf = get_step(left_turf, left_dir) + level_turfs += left_turf + for(var/right_i in 1 to i -calculate_cone_shape(i)) + if(right_turf.density && respect_density) + break + right_turf = get_step(right_turf, right_dir) + level_turfs += right_turf + turfs_to_return += list(level_turfs) + if(i == cone_levels) + continue + if(turf_to_use.density && respect_density) + break + return turfs_to_return + +/obj/effect/proc_holder/spell/cone/cast(list/targets,mob/user = usr) + var/list/cone_turfs = cone_helper(get_turf(user), user.dir, cone_levels) + for(var/list/turf_list in cone_turfs) + do_cone_effects(turf_list) + +///This proc does obj, mob and turf cone effects on all targets in a list +/obj/effect/proc_holder/spell/cone/proc/do_cone_effects(list/target_turf_list, level) + for(var/target_turf in target_turf_list) + if(!target_turf) //if turf is no longer there + continue + do_turf_cone_effect(target_turf, level) + if(isopenturf(target_turf)) + var/turf/open/open_turf = target_turf + for(var/movable_content in open_turf) + if(isobj(movable_content)) + do_obj_cone_effect(movable_content, level) + else if(isliving(movable_content)) + do_mob_cone_effect(movable_content, level) + +///This proc deterimines how the spell will affect turfs. +/obj/effect/proc_holder/spell/cone/proc/do_turf_cone_effect(turf/target_turf, level) + return + +///This proc deterimines how the spell will affect objects. +/obj/effect/proc_holder/spell/cone/proc/do_obj_cone_effect(obj/target_obj, level) + return + +///This proc deterimines how the spell will affect mobs. +/obj/effect/proc_holder/spell/cone/proc/do_mob_cone_effect(mob/living/target_mob, level) + return + +///This proc adjusts the cones width depending on the level. +/obj/effect/proc_holder/spell/cone/proc/calculate_cone_shape(current_level) + var/end_taper_start = round(cone_levels * 0.8) + if(current_level > end_taper_start) + return (current_level % end_taper_start) * 2 //someone more talented and probably come up with a better formula. + else + return 2 + +///This type of cone gradually affects each level of the cone instead of affecting the entire area at once. +/obj/effect/proc_holder/spell/cone/staggered + +/obj/effect/proc_holder/spell/cone/staggered/cast(list/targets,mob/user = usr) + var/level_counter = 0 + var/list/cone_turfs = cone_helper(get_turf(user), user.dir, cone_levels) + for(var/list/turf_list in cone_turfs) + level_counter++ + addtimer(CALLBACK(src, .proc/do_cone_effects, turf_list, level_counter), 2 * level_counter) diff --git a/icons/effects/160x160.dmi b/icons/effects/160x160.dmi index 082078fa0be..12ea4c2decb 100644 Binary files a/icons/effects/160x160.dmi and b/icons/effects/160x160.dmi differ diff --git a/icons/effects/eldritch.dmi b/icons/effects/eldritch.dmi index 00235fb7b5c..349dbd1cc1c 100644 Binary files a/icons/effects/eldritch.dmi and b/icons/effects/eldritch.dmi differ diff --git a/icons/mob/actions/actions_elites.dmi b/icons/mob/actions/actions_elites.dmi index 335261b0f64..c9b769a0c8f 100644 Binary files a/icons/mob/actions/actions_elites.dmi and b/icons/mob/actions/actions_elites.dmi differ