Ports Anti-magic from TG. (#27560)

* the rest of the fucking owl

* OK hands need work but otherwise good

* fuck time out fix vampire after

* temporary codersprite do not merge this lmao

* codersprite up

* pause, time out

* deploy the antimagic

* Update code/__HELPERS/trait_helpers.dm

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com>

* Update code/datums/status_effects/buffs.dm

Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com>

* Update code/game/gamemodes/wizard/magic_tarot.dm

Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com>

---------

Signed-off-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com>
Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com>
Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
Qwertytoforty
2025-01-02 08:36:07 +00:00
committed by GitHub
co-authored by DGamerL Burzah
parent 6057ff5c31
commit 7bbebbb23f
62 changed files with 580 additions and 28 deletions
@@ -301,6 +301,7 @@
clothes_req = FALSE
stat_allowed = CONSCIOUS
antimagic_flags = NONE
selection_activated_message = "<span class='notice'>Your mind grow cold. Click on a target to cast the spell.</span>"
selection_deactivated_message = "<span class='notice'>Your mind returns to normal.</span>"
@@ -372,6 +373,7 @@
clothes_req = FALSE
stat_allowed = CONSCIOUS
invocation_type = "none"
antimagic_flags = NONE
action_icon_state = "genetic_eat"
@@ -511,6 +513,7 @@
clothes_req = FALSE
stat_allowed = CONSCIOUS
invocation_type = "none"
antimagic_flags = NONE
action_icon_state = "genetic_jump"
var/leap_distance = 10
@@ -636,6 +639,7 @@
selection_deactivated_message = "<span class='notice'>Your body calms down again.</span>"
invocation_type = "none"
antimagic_flags = NONE
action_icon_state = "genetic_poly"
@@ -684,6 +688,7 @@
human_req = TRUE
stat_allowed = CONSCIOUS
invocation_type = "none"
antimagic_flags = MAGIC_RESISTANCE_MIND
action_icon_state = "genetic_empath"
@@ -793,6 +798,7 @@
clothes_req = FALSE
stat_allowed = CONSCIOUS
invocation_type = "none"
antimagic_flags = NONE
action_icon_state = "genetic_morph"
@@ -983,6 +989,7 @@
clothes_req = FALSE
stat_allowed = CONSCIOUS
invocation_type = "none"
antimagic_flags = MAGIC_RESISTANCE_MIND
action_icon_state = "genetic_project"
@@ -1017,6 +1024,7 @@
base_cooldown = 0
clothes_req = FALSE
stat_allowed = CONSCIOUS
antimagic_flags = MAGIC_RESISTANCE_MIND
invocation_type = "none"
action_icon_state = "genetic_mindscan"
var/list/expanded_minds = list()
@@ -1105,6 +1113,7 @@
clothes_req = FALSE
stat_allowed = CONSCIOUS
invocation_type = "none"
antimagic_flags = MAGIC_RESISTANCE_MIND
action_icon_state = "genetic_view"
+6
View File
@@ -385,6 +385,7 @@
var/uses = 1
var/health_cost = 0 //The amount of health taken from the user when invoking the spell
var/datum/action/innate/cult/blood_spell/source
var/antimagic_flags = MAGIC_RESISTANCE_HOLY
/obj/item/melee/blood_magic/Initialize(mapload, spell)
. = ..()
@@ -418,6 +419,11 @@
uses = 0
qdel(src)
return
if(M.can_block_magic(MAGIC_RESISTANCE_HOLY))
to_chat(user, "<span class='danger'>[M] absorbs your spell!</span>")
uses = 0
qdel(src)
return
add_attack_logs(user, M, "used a cult spell ([src]) on")
M.lastattacker = user.real_name
+2 -3
View File
@@ -249,9 +249,8 @@ structure_check() searches for nearby cultist structures required for the invoca
qdel(src)
/mob/proc/null_rod_check() //The null rod, if equipped, will protect the holder from the effects of most runes
var/obj/item/nullrod/N = locate() in src
if(N)
return N
if(can_block_magic(MAGIC_RESISTANCE_HOLY))
return TRUE
return FALSE
//Rite of Enlightenment: Converts a normal crewmember to the cult, or offer them as sacrifice if cant be converted.
@@ -13,6 +13,7 @@
base_cooldown = 0
var/uses //If we have multiple uses of the same power
var/auto_use_uses = TRUE //If we automatically use up uses on each activation
antimagic_flags = NONE
/datum/spell/ai_spell/create_new_targeting()
return new /datum/spell_targeting/self
@@ -212,6 +212,8 @@
return
hit = TRUE // to prevent double hits from the pull
. = ..()
if(!.)
return
for(var/atom/extinguish_target in range(2, src))
extinguish_target.extinguish_light(TRUE)
if(!isliving(target))
@@ -106,6 +106,7 @@
name = "Place Teleportation Beacon"
desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon requires an anchor, will not work on space tiles."
clothes_req = FALSE
antimagic_flags = NONE
base_cooldown = 300 SECONDS
action_icon_state = "no_state"
action_background_icon = 'icons/mob/guardian.dmi'
@@ -129,6 +130,7 @@
name = "Set Surveillance Snare"
desc = "Places an invisible Surveillance Snare on the ground, if someone walks over it you'll be alerted. Max of 6 snares active at a time"
clothes_req = FALSE
antimagic_flags = NONE
base_cooldown = 3 SECONDS
action_icon_state = "no_state"
action_background_icon = 'icons/mob/guardian.dmi'
@@ -160,6 +162,7 @@
name = "Change battlecry"
desc = "Changes your battlecry."
clothes_req = FALSE
antimagic_flags = NONE
base_cooldown = 1 SECONDS
action_icon_state = "no_state"
action_background_icon = 'icons/mob/guardian.dmi'
@@ -5,6 +5,7 @@
action_background_icon_state = "bg_morph"
action_icon_state = "morph_airlock"
clothes_req = FALSE
antimagic_flags = NONE
base_cooldown = 10 SECONDS
selection_activated_message = "<span class='sinister'>Click on an airlock to try pass it.</span>"
@@ -10,6 +10,7 @@
/datum/spell/pulse_demon
clothes_req = FALSE
antimagic_flags = NONE
action_background_icon_state = "bg_pulsedemon"
var/locked = TRUE
var/unlock_cost = 1 KJ
@@ -134,6 +134,7 @@
clothes_req = FALSE
action_icon_state = "r_transmit"
action_background_icon_state = "bg_revenant"
antimagic_flags = MAGIC_RESISTANCE_HOLY|MAGIC_RESISTANCE_MIND
/datum/spell/revenant_transmit/create_new_targeting()
var/datum/spell_targeting/targeted/T = new()
@@ -165,6 +166,7 @@
var/unlock_amount = 100
/// How much essence it costs to use
var/cast_amount = 50
antimagic_flags = MAGIC_RESISTANCE_HOLY
/datum/spell/aoe/revenant/New()
..()
+24 -5
View File
@@ -16,6 +16,8 @@
throw_range = 0
throw_speed = 0
new_attack_chain = TRUE
/// Has it been blocked by antimagic? If so, abort.
var/blocked_by_antimagic = FALSE
/obj/item/melee/touch_attack/New(spell)
attached_spell = spell
@@ -37,6 +39,17 @@
to_chat(user, "<span class='warning'>You can't reach out!</span>")
return FINISH_ATTACK
/obj/item/melee/touch_attack/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
var/mob/mob_victim = target
if(istype(mob_victim) && mob_victim.can_block_magic(attached_spell.antimagic_flags))
to_chat(user, "<span class='danger'>[mob_victim] absorbs your spell!</span>")
blocked_by_antimagic = TRUE
if(attached_spell && attached_spell.cooldown_handler)
attached_spell.cooldown_handler.start_recharge(attached_spell.cooldown_handler.recharge_duration * 0.5)
qdel(src)
return
/obj/item/melee/touch_attack/proc/handle_delete(mob/user)
if(catchphrase)
user.say(catchphrase)
@@ -53,9 +66,10 @@
icon_state = "disintegrate"
item_state = "disintegrate"
/obj/item/melee/touch_attack/disintegrate/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!proximity_flag || target == user || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //exploding after touching yourself would be bad
if(!proximity_flag || target == user || blocked_by_antimagic || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //exploding after touching yourself would be bad
return
var/mob/M = target
do_sparks(4, 0, M.loc) //no idea what the 0 is
@@ -72,7 +86,8 @@
/obj/item/melee/touch_attack/fleshtostone/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!proximity_flag || target == user || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //getting hard after touching yourself would also be bad
if(!proximity_flag || target == user || blocked_by_antimagic || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //getting hard after touching yourself would also be bad
return
var/mob/living/L = target
L.Stun(4 SECONDS)
@@ -90,12 +105,14 @@
/obj/item/melee/touch_attack/plushify/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!proximity_flag || target == user || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //There are better ways to get a good nights sleep in a bed.
if(!proximity_flag || target == user || blocked_by_antimagic || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //There are better ways to get a good nights sleep in a bed.
return
var/mob/living/L = target
L.plushify()
handle_delete(user)
/obj/item/melee/touch_attack/fake_disintegrate
name = "toy plastic hand"
desc = "This hand of mine glows with an awesome power! Ok, maybe just batteries."
@@ -107,7 +124,8 @@
/obj/item/melee/touch_attack/fake_disintegrate/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!proximity_flag || target == user || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //not exploding after touching yourself would be bad
if(!proximity_flag || target == user || blocked_by_antimagic || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //not exploding after touching yourself would be bad
return
do_sparks(4, 0, target.loc)
playsound(target.loc, 'sound/goonstation/effects/gib.ogg', 50, 1)
@@ -123,7 +141,8 @@
/obj/item/melee/touch_attack/cluwne/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!proximity_flag || target == user || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //clowning around after touching yourself would unsurprisingly, be bad
if(!proximity_flag || target == user || blocked_by_antimagic || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //clowning around after touching yourself would unsurprisingly, be bad
return
if(iswizard(target))
+17 -1
View File
@@ -232,6 +232,11 @@
qdel(src)
/obj/item/magic_tarot_card/proc/pre_activate(mob/user, atom/movable/thrower)
if(user != thrower) //Ignore antimagic stuff if the user is the thrower (aka self activation)
if(user.can_block_magic(our_tarot.antimagic_flags, 1))
visible_message("<span class='warning'>[src] burns up in a flash on contact with [user]!</span>")
qdel(src)
return
has_been_activated = TRUE
forceMove(user)
var/obj/effect/temp_visual/card_preview/tarot/draft = new(user, "tarot_[our_tarot.card_icon]")
@@ -288,6 +293,8 @@
var/card_icon = "the_unknown"
/// Are we reversed? Used for the card back.
var/reversed = FALSE
/// What antimagic flags do we have?
var/antimagic_flags = MAGIC_RESISTANCE
/datum/tarot/proc/activate(mob/living/target)
stack_trace("A bugged tarot card was spawned and used. Please make an issue report! Type was [src.type]")
@@ -688,8 +695,11 @@
var/sparkle_path = /obj/effect/temp_visual/gravpush
for(var/turf/T in range(5, target)) //Done this way so things don't get thrown all around hilariously.
for(var/atom/movable/AM in T)
if(ismob(AM))
var/mob/victim_mob = AM
if(victim_mob.can_block_magic(antimagic_flags))
continue
thrown_atoms += AM
for(var/atom/movable/AM as anything in thrown_atoms)
if(AM == target || AM.anchored || (ismob(AM) && !isliving(AM)))
continue
@@ -729,6 +739,9 @@
/datum/tarot/reversed/the_empress/activate(mob/living/target)
for(var/mob/living/L in oview(9, target))
if(L.can_block_magic(antimagic_flags))
to_chat(L, "<span class='notice'>You feel calm for a second, but it quickly passes.</span>")
continue
L.apply_status_effect(STATUS_EFFECT_PACIFIED)
/datum/tarot/reversed/the_emperor
@@ -763,6 +776,8 @@
for(var/mob/living/M in shuffle(orange(7, target)))
if(M.stat == DEAD) //Let us not have dead mobs be used to make a disco inferno.
continue
if(M.can_block_magic(antimagic_flags)) //Be spared!
continue
if(active_chasers >= 2)
return
var/obj/effect/temp_visual/hierophant/chaser/C = new(get_turf(target), target, M, 1, FALSE)
@@ -959,6 +974,7 @@
desc = "May you remember lost memories."
extended_desc = "will reveal the memories of everyone in range to the user."
card_icon = "the_moon?"
antimagic_flags = MAGIC_RESISTANCE|MAGIC_RESISTANCE_MIND
/datum/tarot/reversed/the_moon/activate(mob/living/target)
for(var/mob/living/L in view(5, target)) //Shorter range as this kinda can give away antagonists, though that is also funny.
+3 -1
View File
@@ -499,7 +499,9 @@
//Weapons and Armors
/datum/spellbook_entry/item/battlemage
name = "Battlemage Armor"
desc = "An ensorceled spaceproof suit of protective yet light armor, protected by a powerful shield. The shield can completely negate 15 attacks before permanently failing."
desc = "An ensorceled spaceproof suit of protective yet light armor, protected by a powerful shield. The shield can completely negate 15 attacks before permanently failing. \
This armor grants you full protection from magical attacks, and allows you to cast magic despite that. However, this means it will also block wands or staffs of \
healing from working on you, and should be removed before application."
item_path = /obj/item/storage/box/wizard/hardsuit
limit = 1
category = "Weapons and Armors"
+6
View File
@@ -17,6 +17,8 @@
/obj/effect/forcefield/wizard
var/mob/wizard
/// Flags for what antimagic can just ignore our forcefields
var/antimagic_flags = MAGIC_RESISTANCE
/obj/effect/forcefield/wizard/Initialize(mapload, mob/summoner)
. = ..()
@@ -25,6 +27,10 @@
/obj/effect/forcefield/wizard/CanPass(atom/movable/mover, border_dir)
if(mover == wizard)
return TRUE
if(isliving(mover))
var/mob/living/living_mover = mover
if(living_mover.can_block_magic(antimagic_flags, charge_cost = 0))
return TRUE
return FALSE
///////////Mimewalls///////////
@@ -21,9 +21,12 @@
var/list/fluff_transformations = list()
/// Extra 'Holy' burn damage for ERT null rods
var/sanctify_force = 0
/// The antimagic type the nullrod has.
var/antimagic_type = MAGIC_RESISTANCE_HOLY
/obj/item/nullrod/Initialize(mapload)
. = ..()
AddComponent(/datum/component/anti_magic, antimagic_type)
if(!length(variant_names))
for(var/I in typesof(/obj/item/nullrod))
var/obj/item/nullrod/rod = I
@@ -37,11 +40,6 @@
/obj/item/nullrod/attack__legacy__attackchain(mob/M, mob/living/carbon/user)
..()
var/datum/antagonist/vampire/V = M.mind?.has_antag_datum(/datum/antagonist/vampire)
if(ishuman(M) && V && HAS_MIND_TRAIT(M, TRAIT_HOLY))
if(!V.get_ability(/datum/vampire_passive/full))
to_chat(M, "<span class='warning'>The nullrod's power interferes with your own!</span>")
V.adjust_nullification(30 + sanctify_force, 15 + sanctify_force)
if(!sanctify_force)
return
if(isliving(M))
@@ -593,6 +591,16 @@
to_chat(user, "<span class='notice'>Your prayer to [SSticker.Bible_deity_name] was interrupted.</span>")
praying = FALSE
/obj/item/nullrod/nazar
name = "nazar"
icon_state = "nazar"
item_state = null
desc = "A set of glass beads and amulet, which has been forged to provide powerful magic protection to the wielder."
force = 0
throwforce = 0
antimagic_type = ALL
/obj/item/nullrod/salt
name = "Holy Salt"
icon = 'icons/obj/food/containers.dmi'