diff --git a/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm b/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm
index 4135269219..b9bc8bc2c4 100644
--- a/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm
+++ b/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm
@@ -40,5 +40,4 @@
else
L.electrocute_act(power, src, 0.75, BP_TORSO)
-
- adjust_instability(3)
\ No newline at end of file
+ adjust_instability(3)
diff --git a/code/modules/mob/_modifiers/feysight.dm b/code/modules/mob/_modifiers/feysight.dm
new file mode 100644
index 0000000000..af391ed51c
--- /dev/null
+++ b/code/modules/mob/_modifiers/feysight.dm
@@ -0,0 +1,42 @@
+/datum/modifier/feysight
+ name = "feysight"
+ desc = "You are filled with an inner peace, and widened sight."
+ client_color = "#42e6ca"
+
+ on_created_text = "You feel an inner peace as your mind's eye expands!"
+ on_expired_text = "Your sight returns to what it once was."
+ stacks = MODIFIER_STACK_EXTEND
+
+ accuracy = -15
+ accuracy_dispersion = 1
+
+/datum/modifier/feysight/on_applied()
+ holder.see_invisible = 60
+ holder.see_invisible_default = 60
+
+/datum/modifier/feysight/on_expire()
+ holder.see_invisible_default = initial(holder.see_invisible_default)
+ holder.see_invisible = holder.see_invisible_default
+
+/datum/modifier/feysight/can_apply(var/mob/living/L)
+ if(L.stat)
+ to_chat(L, "You can't be unconscious or dead to experience tranquility.")
+ return FALSE
+
+ if(!L.is_sentient())
+ return FALSE // Drones don't feel anything.
+
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ if(H.species.name == "Diona")
+ to_chat(L, "You feel strange for a moment, but it passes.")
+ return FALSE // Happy trees aren't affected by tranquility.
+
+ return ..()
+
+/datum/modifier/feysight/tick()
+ ..()
+
+ if(ishuman(holder))
+ var/mob/living/carbon/human/H = holder
+ H.druggy = min(15, H.druggy + 4)
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/bats.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/bats.dm
index 7397636686..7ca24f3174 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/space/bats.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/bats.dm
@@ -50,3 +50,8 @@
/mob/living/simple_mob/animal/space/bats/cult/cultify()
return
+
+/mob/living/simple_mob/animal/space/bats/cult/strong
+ maxHealth = 60
+ health = 60
+ melee_damage_upper = 10
diff --git a/code/modules/shieldgen/energy_field.dm b/code/modules/shieldgen/energy_field.dm
index 5b7d7f2118..87d07cceaf 100644
--- a/code/modules/shieldgen/energy_field.dm
+++ b/code/modules/shieldgen/energy_field.dm
@@ -31,8 +31,14 @@
/obj/effect/energy_field/Destroy()
update_nearby_tiles()
- my_gen.field.Remove(src)
- my_gen = null
+ if(my_gen)
+ if(istype(my_gen))
+ my_gen.field.Remove(src)
+ my_gen = null
+ else if(istype(my_gen, /datum/artifact_effect/forcefield))
+ var/datum/artifact_effect/forcefield/AE = my_gen
+ AE.created_field.Remove(src)
+ my_gen = null
var/turf/current_loc = get_turf(src)
. = ..()
for(var/direction in cardinal)
diff --git a/code/modules/xenoarcheaology/effects/cannibal.dm b/code/modules/xenoarcheaology/effects/cannibal.dm
new file mode 100644
index 0000000000..04a0b5a9e8
--- /dev/null
+++ b/code/modules/xenoarcheaology/effects/cannibal.dm
@@ -0,0 +1,75 @@
+/datum/artifact_effect/cannibalfeeling
+ name = "cannibalfeeling"
+ effect_type = EFFECT_PSIONIC
+ var/list/messages = list("You feel peckish.",
+ "Something doesn't feel right.",
+ "You get a strange feeling in your gut.",
+ "You feel particularly hungry.",
+ "You taste blood.",
+ "There's a strange feeling in the air.",
+ "There's a strange smell in the air.",
+ "The tips of your fingers feel tingly.",
+ "You feel twitchy.",
+ "You feel empty.",
+ "You've got a good feeling about this.",
+ "Your tongue prickles.",
+ "Are they clean?",
+ "You feel weak.",
+ "The ground is getting closer.",
+ "Something is missing.")
+
+ var/list/drastic_messages = list("They look delicious.",
+ "They'll take what's yours!",
+ "They're full of meat.",
+ "What's happening to you?",
+ "Butcher them!",
+ "Feast!")
+
+/datum/artifact_effect/cannibalfeeling/DoEffectTouch(var/mob/user)
+ if(user)
+ if (istype(user, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ if(H.is_sentient())
+ if(prob(50))
+ if(prob(75))
+ to_chat(H, "[pick(drastic_messages)]")
+ else
+ to_chat(H, "[pick(messages)]")
+
+ if(prob(50))
+ H.dizziness += rand(3,5)
+ H.nutrition = H.nutrition / 1.5
+
+/datum/artifact_effect/cannibalfeeling/DoEffectAura()
+ if(holder)
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/human/H in range(src.effectrange,T))
+ if(H.is_sentient())
+ if(prob(5))
+ if(prob(75))
+ to_chat(H, "[pick(messages)]")
+ else
+ to_chat(H, "[pick(drastic_messages)]")
+
+ if(prob(10))
+ H.dizziness += rand(3,5)
+ H.nutrition = H.nutrition / 2
+ return 1
+
+/datum/artifact_effect/cannibalfeeling/DoEffectPulse()
+ if(holder)
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/human/H in range(src.effectrange,T))
+ if(H.is_sentient())
+ if(prob(50))
+ if(prob(95))
+ to_chat(H, "[pick(drastic_messages)]")
+ else
+ to_chat(H, "[pick(messages)]")
+
+ if(prob(50))
+ H.dizziness += rand(3,5)
+ else if(prob(25))
+ H.dizziness += rand(5,15)
+ H.nutrition = H.nutrition / 4
+ return 1
diff --git a/code/modules/xenoarcheaology/effects/electric_field.dm b/code/modules/xenoarcheaology/effects/electric_field.dm
new file mode 100644
index 0000000000..3b27e8fe42
--- /dev/null
+++ b/code/modules/xenoarcheaology/effects/electric_field.dm
@@ -0,0 +1,69 @@
+
+/datum/artifact_effect/electric_field
+ name = "electric field"
+ effect_type = EFFECT_ENERGY
+
+/datum/artifact_effect/electric_field/DoEffectTouch(var/mob/user)
+ var/list/nearby_mobs = list()
+ for(var/mob/living/L in oview(effectrange, get_turf(holder)))
+ if(L == user) // You're "grounded" when you contact the artifact.
+ continue
+ if(!L.stat)
+ nearby_mobs |= L
+
+ for(var/obj/machinery/light/light in range(effectrange, get_turf(holder)))
+ light.flicker()
+
+ for(var/mob/living/L in nearby_mobs)
+ if(L.isSynthetic())
+ to_chat(L, "ERROR: Electrical fault detected!")
+ L.stuttering += 3
+
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ var/obj/item/organ/external/affected = H.get_organ(check_zone(BP_TORSO))
+ H.electrocute_act(rand(25, 40), holder, H.get_siemens_coefficient_organ(affected), affected)
+ else
+ L.electrocute_act(rand(25, 40), holder, 0.75, BP_TORSO)
+
+/datum/artifact_effect/electric_field/DoEffectAura()
+ var/list/nearby_mobs = list()
+ for(var/mob/living/L in oview(effectrange, get_turf(holder)))
+ if(!L.stat)
+ nearby_mobs |= L
+
+ for(var/obj/machinery/light/light in range(effectrange, get_turf(holder)))
+ light.flicker()
+
+ for(var/mob/living/L in nearby_mobs)
+ if(L.isSynthetic())
+ to_chat(L, "ERROR: Electrical fault detected!")
+ L.stuttering += 3
+
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ var/obj/item/organ/external/affected = H.get_organ(check_zone(BP_TORSO))
+ H.electrocute_act(rand(1, 10), holder, H.get_siemens_coefficient_organ(affected), affected)
+ else
+ L.electrocute_act(rand(1, 10), holder, 0.75, BP_TORSO)
+
+/datum/artifact_effect/electric_field/DoEffectPulse()
+ var/list/nearby_mobs = list()
+ for(var/mob/living/L in oview(effectrange, get_turf(holder)))
+ if(!L.stat)
+ nearby_mobs |= L
+
+ for(var/obj/machinery/light/light in range(effectrange, get_turf(holder)))
+ light.flicker()
+
+ for(var/mob/living/L in nearby_mobs)
+ if(L.isSynthetic())
+ to_chat(L, "ERROR: Electrical fault detected!")
+ L.stuttering += 3
+
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ var/obj/item/organ/external/affected = H.get_organ(check_zone(BP_TORSO))
+ H.electrocute_act(rand(10, 30), holder, H.get_siemens_coefficient_organ(affected), affected)
+ else
+ L.electrocute_act(rand(10, 30), holder, 0.75, BP_TORSO)
diff --git a/code/modules/xenoarcheaology/effects/feysight.dm b/code/modules/xenoarcheaology/effects/feysight.dm
new file mode 100644
index 0000000000..379dc0cc54
--- /dev/null
+++ b/code/modules/xenoarcheaology/effects/feysight.dm
@@ -0,0 +1,43 @@
+/datum/artifact_effect/feysight
+ name = "feysight"
+ effect_type = EFFECT_PSIONIC
+
+/datum/artifact_effect/feysight/proc/apply_modifier(var/mob/living/L)
+ if(!istype(L))
+ return FALSE
+
+ if(!L.is_sentient())
+ return FALSE // Drons are presumably deaf to any psionic things.
+
+ if(L.add_modifier(/datum/modifier/feysight, 30 SECONDS))
+ to_chat(L, "An otherworldly feeling seems to enter your mind, and you feel at peace.")
+ L.adjustHalLoss(10)
+ to_chat(L, "The inside of your head hurts...")
+ return TRUE
+ else
+ if(L.has_modifier_of_type(/datum/modifier/feysight))
+ to_chat(L, "An otherworldly feeling seems to enter your mind again, and it holds the visions in place.")
+ else
+ to_chat(L, "An otherworldly feeling seems to enter your mind, and you briefly feel peace, but \
+ it quickly passes.")
+ return FALSE
+
+/datum/artifact_effect/feysight/DoEffectTouch(var/mob/toucher)
+ if(toucher && isliving(toucher))
+ apply_modifier(toucher)
+ return TRUE
+
+/datum/artifact_effect/feysight/DoEffectAura()
+ if(holder)
+ var/turf/T = get_turf(holder)
+ for(var/mob/living/L in range(src.effectrange,T))
+ if(prob(10))
+ apply_modifier(L)
+ return TRUE
+
+/datum/artifact_effect/feysight/DoEffectPulse()
+ if(holder)
+ var/turf/T = get_turf(holder)
+ for(var/mob/living/L in range(src.effectrange,T))
+ apply_modifier(L)
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/xenoarcheaology/effects/gaia.dm b/code/modules/xenoarcheaology/effects/gaia.dm
new file mode 100644
index 0000000000..1a89149818
--- /dev/null
+++ b/code/modules/xenoarcheaology/effects/gaia.dm
@@ -0,0 +1,81 @@
+
+/datum/artifact_effect/gaia
+ name = "gaia"
+ effect_type = EFFECT_ORGANIC
+
+ var/list/my_glitterflies = list()
+
+/datum/artifact_effect/gaia/proc/age_plantlife(var/obj/machinery/portable_atmospherics/hydroponics/Tray = null)
+ if(istype(Tray) && Tray.seed)
+ Tray.health += rand(1,3) * HYDRO_SPEED_MULTIPLIER
+ Tray.age += 1
+
+ if(Tray.health > 0 && Tray.dead)
+ Tray.dead = FALSE
+
+ Tray.check_health()
+
+ if(!Tray.dead)
+ if((Tray.age > Tray.seed.get_trait(TRAIT_MATURATION)) && \
+ ((Tray.age - Tray.lastproduce) > Tray.seed.get_trait(TRAIT_PRODUCTION)) && \
+ (!Tray.harvest && !Tray.dead))
+ Tray.harvest = 1
+ Tray.lastproduce = Tray.age
+
+ else if(istype(Tray, /obj/effect/plant))
+ var/obj/effect/plant/P = Tray
+ Tray = P.plant
+ if(Tray)
+ age_plantlife(Tray)
+ P.update_icon()
+
+/datum/artifact_effect/gaia/DoEffectTouch(var/mob/user)
+ to_chat(user, "You feel the presence of something long forgotten.")
+ for(var/obj/machinery/portable_atmospherics/hydroponics/Tray in view(world.view,get_turf(holder)))
+ age_plantlife(Tray)
+ if(prob(30))
+ var/mob/living/simple_mob/animal/sif/glitterfly/G = new(get_turf(Tray))
+
+ my_glitterflies |= G
+
+ G.ai_holder.returns_home = TRUE
+
+ for(var/obj/effect/plant/P in view(world.view,get_turf(holder)))
+ age_plantlife(P)
+
+/datum/artifact_effect/gaia/DoEffectAura()
+ for(var/obj/machinery/portable_atmospherics/hydroponics/Tray in view(effectrange,holder))
+ age_plantlife(Tray)
+ if(prob(2))
+ var/mob/living/simple_mob/animal/sif/glitterfly/G = new(get_turf(Tray))
+
+ my_glitterflies |= G
+
+ G.ai_holder.returns_home = TRUE
+
+ for(var/obj/effect/plant/P in view(effectrange,get_turf(holder)))
+ age_plantlife(P)
+
+/datum/artifact_effect/gaia/DoEffectPulse()
+ for(var/obj/machinery/portable_atmospherics/hydroponics/Tray in view(effectrange,holder))
+ age_plantlife(Tray)
+ if(prob(10))
+ var/mob/living/simple_mob/animal/sif/glitterfly/G = new(get_turf(Tray))
+
+ my_glitterflies |= G
+
+ G.ai_holder.returns_home = TRUE
+
+ for(var/obj/effect/plant/P in view(effectrange,get_turf(holder)))
+ age_plantlife(P)
+
+/datum/artifact_effect/gaia/process()
+ ..()
+
+ listclearnulls(my_glitterflies)
+
+ for(var/mob/living/L in my_glitterflies)
+ if(L.stat == DEAD)
+ my_glitterflies -= L
+
+ L.ai_holder.home_turf = get_turf(holder)
diff --git a/code/modules/xenoarcheaology/effects/gravitational_waves.dm b/code/modules/xenoarcheaology/effects/gravitational_waves.dm
index 431a984191..8483d23d4b 100644
--- a/code/modules/xenoarcheaology/effects/gravitational_waves.dm
+++ b/code/modules/xenoarcheaology/effects/gravitational_waves.dm
@@ -14,12 +14,12 @@
if(prob(10 + seconds_since_last_pull))
holder.visible_message("\The [holder] distorts as local gravity intensifies, and shifts toward it.")
last_wave_pull = world.time
- gravwave(holder, effectrange, STAGE_TWO)
+ gravwave(get_turf(holder), effectrange, STAGE_TWO)
/datum/artifact_effect/gravity_wave/DoEffectPulse()
holder.visible_message("\The [holder] distorts as local gravity intensifies, and shifts toward it.")
- gravwave(holder, effectrange, STAGE_TWO)
+ gravwave(get_turf(holder), effectrange, STAGE_TWO)
proc/gravwave(var/atom/target, var/pull_range = 7, var/pull_power = STAGE_TWO)
- for(var/atom/A in view(pull_range, target))
+ for(var/atom/A in oview(pull_range, target))
A.singularity_pull(target, pull_power)
diff --git a/code/modules/xenoarcheaology/effects/poltergeist.dm b/code/modules/xenoarcheaology/effects/poltergeist.dm
index dac2b35bec..189c0ea4cd 100644
--- a/code/modules/xenoarcheaology/effects/poltergeist.dm
+++ b/code/modules/xenoarcheaology/effects/poltergeist.dm
@@ -6,25 +6,25 @@
/datum/artifact_effect/poltergeist/proc/throw_at_mob(var/mob/living/target, var/damage = 20)
var/list/valid_targets = list()
- for(var/obj/O in view(world.view, target))
- if(!O.anchored)
+ for(var/obj/O in oview(world.view, target))
+ if(!O.anchored && isturf(O.loc))
valid_targets |= O
if(valid_targets.len)
var/obj/obj_to_throw = pick(valid_targets)
obj_to_throw.visible_message("\The [obj_to_throw] levitates, befure hurtling toward [target]!")
- obj_to_throw.throw_at(target, world.view, damage * GetAnomalySusceptibility(target))
+ obj_to_throw.throw_at(target, world.view, min(40, damage * GetAnomalySusceptibility(target)))
/datum/artifact_effect/poltergeist/DoEffectTouch(var/mob/user)
throw_at_mob(user, rand(10, 30))
/datum/artifact_effect/poltergeist/DoEffectAura()
var/mob/living/target = null
- for(var/mob/living/L in view(holder, effectrange))
+ for(var/mob/living/L in oview(get_turf(holder), effectrange))
if(L.stat || !L.mind)
continue
- if(target && get_dist(holder, L) > get_dist(holder, target))
+ if(target && get_dist(get_turf(holder), L) > get_dist(get_turf(holder), target))
continue
target = L
@@ -34,11 +34,11 @@
/datum/artifact_effect/poltergeist/DoEffectPulse()
var/mob/living/target = null
- for(var/mob/living/L in view(holder, effectrange))
+ for(var/mob/living/L in oview(get_turf(holder), effectrange))
if(L.stat || !L.mind)
continue
- if(target && get_dist(holder, L) > get_dist(holder, target))
+ if(target && get_dist(get_turf(holder), L) > get_dist(get_turf(holder), target))
continue
target = L
diff --git a/code/modules/xenoarcheaology/effects/resurrect.dm b/code/modules/xenoarcheaology/effects/resurrect.dm
new file mode 100644
index 0000000000..e54ca276ea
--- /dev/null
+++ b/code/modules/xenoarcheaology/effects/resurrect.dm
@@ -0,0 +1,100 @@
+/datum/artifact_effect/resurrect
+ name = "resurrect"
+ effect_type = EFFECT_ORGANIC
+
+ var/stored_life = 0
+
+/datum/artifact_effect/resurrect/proc/steal_life(var/mob/living/target = null)
+ if(!istype(target))
+ return 0
+
+ if(target.stat != DEAD && stored_life < 200)
+ holder.Beam(target, icon_state = "drain_life", time = 1 SECOND)
+ target.apply_damage(5, SEARING, BP_TORSO)
+ return 5
+
+ return 0
+
+/datum/artifact_effect/resurrect/proc/give_life(var/mob/living/target = null)
+ if(!istype(target))
+ return
+
+ if(target.stat == DEAD && stored_life)
+ holder.Beam(target, icon_state = "lichbeam", time = 1 SECOND)
+ target.adjustBruteLoss(-5)
+ target.adjustFireLoss(-5)
+ target.adjustCloneLoss(-5)
+ target.adjustOxyLoss(-5)
+ target.adjustHalLoss(-5)
+ target.adjustToxLoss(-5)
+ stored_life = max(0, stored_life - 5)
+
+ if(target.health > (target.maxHealth / 4))
+ attempt_revive(target)
+ stored_life = 0
+
+/datum/artifact_effect/resurrect/proc/attempt_revive(var/mob/living/L = null)
+ spawn()
+ if(istype(L, /mob/living/simple_mob))
+ var/mob/living/simple_mob/SM = L
+ SM.adjustBruteLoss(-40)
+ SM.adjustFireLoss(-40)
+ SM.health = SM.getMaxHealth() / 3
+ SM.stat = CONSCIOUS
+ dead_mob_list -= SM
+ living_mob_list += SM
+ SM.update_icon()
+ SM.revive()
+ holder.visible_message("\The [SM]'s eyes open in a flash of light!")
+ else if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+
+ if(!H.client && H.mind)
+ for(var/mob/observer/dead/ghost in player_list)
+ if(ghost.mind == H.mind)
+ to_chat(ghost, "An artifact is trying to \
+ revive you. Return to your body if you want to be resurrected! \
+ (Verbs -> Ghost -> Re-enter corpse)")
+ break
+
+ H.adjustBruteLoss(-40)
+ H.adjustFireLoss(-40)
+
+ sleep(10 SECONDS)
+ if(H.client)
+ L.stat = CONSCIOUS
+ dead_mob_list -= H
+ living_mob_list += H
+ H.timeofdeath = null
+
+ holder.visible_message("\The [H]'s eyes open in a flash of light!")
+
+/datum/artifact_effect/resurrect/DoEffectTouch(var/mob/user)
+ for(var/mob/living/L in oview(effectrange, get_turf(holder)))
+ stored_life += 4 * steal_life(L)
+
+ var/turf/T = get_turf(holder)
+ for(var/mob/living/L in T)
+ if(L.stat == DEAD)
+ give_life(L)
+ break
+
+/datum/artifact_effect/resurrect/DoEffectAura()
+ for(var/mob/living/L in oview(effectrange, get_turf(holder)))
+ stored_life += steal_life(L)
+
+ var/turf/T = get_turf(holder)
+ for(var/mob/living/L in T)
+ if(L.stat == DEAD)
+ give_life(L)
+ break
+
+/datum/artifact_effect/resurrect/DoEffectPulse()
+ for(var/mob/living/L in oview(effectrange, get_turf(holder)))
+ stored_life += 2 * steal_life(L)
+
+ var/turf/T = get_turf(holder)
+ for(var/mob/living/L in T)
+ if(L.stat == DEAD)
+ give_life(L)
+ break
diff --git a/code/modules/xenoarcheaology/effects/vampire.dm b/code/modules/xenoarcheaology/effects/vampire.dm
new file mode 100644
index 0000000000..4d084e2a37
--- /dev/null
+++ b/code/modules/xenoarcheaology/effects/vampire.dm
@@ -0,0 +1,86 @@
+
+/datum/artifact_effect/vampire
+ name = "vampire"
+ effect_type = EFFECT_ORGANIC
+ var/last_bloodcall = 0
+ var/bloodcall_interval = 50
+ var/last_eat = 0
+ var/eat_interval = 100
+ var/charges = 0
+ var/list/nearby_mobs = list()
+
+/datum/artifact_effect/vampire/proc/bloodcall(var/mob/living/carbon/human/M)
+ last_bloodcall = world.time
+ if(istype(M))
+ playsound(holder.loc, pick('sound/hallucinations/wail.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/far_noise.ogg'), 50, 1, -3)
+
+ var/target = pick(M.organs_by_name)
+ M.apply_damage(rand(5, 10), SEARING, target)
+ to_chat(M, "The skin on your [parse_zone(target)] feels like it's ripping apart, and a stream of blood flies out.")
+ var/obj/effect/decal/cleanable/blood/splatter/animated/B = new(M.loc)
+ B.basecolor = M.species.get_blood_colour(M)
+ B.color = M.species.get_blood_colour(M)
+ B.target_turf = pick(range(1, get_turf(holder)))
+ B.blood_DNA = list()
+ B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
+ M.vessel.remove_reagent("blood",rand(25,50))
+
+/datum/artifact_effect/vampire/DoEffectTouch(var/mob/user)
+ bloodcall(user)
+ DoEffectAura()
+
+/datum/artifact_effect/vampire/DoEffectAura()
+ nearby_mobs.Cut()
+
+ var/turf/T = get_turf(holder)
+
+ for(var/mob/living/L in oview(effectrange, T))
+ if(!L.stat && L.mind)
+ nearby_mobs |= L
+
+ if(world.time - last_bloodcall > bloodcall_interval && nearby_mobs.len)
+ var/mob/living/carbon/human/M = pick(nearby_mobs)
+ if(M in view(effectrange,holder) && M.health > 20)
+ if(prob(50))
+ bloodcall(M)
+ holder.Beam(M, icon_state = "drainbeam", time = 1 SECOND)
+
+ if(world.time - last_eat > eat_interval)
+ var/obj/effect/decal/cleanable/blood/B = locate() in range(2,holder)
+ if(B)
+ last_eat = world.time
+ B.loc = null
+ if(istype(B, /obj/effect/decal/cleanable/blood/drip))
+ charges += 0.25
+ else
+ charges += 1
+ playsound(holder.loc, 'sound/effects/splat.ogg', 50, 1, -3)
+
+ qdel(B)
+
+ if(charges >= 10)
+ charges -= 10
+ var/manifestation = pick(/obj/item/device/soulstone, /mob/living/simple_mob/faithless/cult/strong, /mob/living/simple_mob/creature/cult/strong, /mob/living/simple_mob/animal/space/bats/cult/strong)
+ new manifestation(pick(view(1,T)))
+
+ if(charges >= 3)
+ if(prob(5))
+ charges -= 1
+ var/spawn_type = pick(/mob/living/simple_mob/animal/space/bats, /mob/living/simple_mob/creature, /mob/living/simple_mob/faithless)
+ new spawn_type(pick(view(1,T)))
+ playsound(holder.loc, pick('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg'), 50, 1, -3)
+
+ if(charges >= 1 && nearby_mobs.len && prob(15 * nearby_mobs.len))
+ var/mob/living/L = pick(nearby_mobs)
+
+ holder.Beam(L, icon_state = "drainbeam", time = 1 SECOND)
+
+ L.add_modifier(/datum/modifier/agonize, 5 SECONDS)
+
+ if(charges >= 0.1)
+ if(prob(5))
+ holder.visible_message("\icon[holder] \The [holder] gleams a bloody red!")
+ charges -= 0.1
+
+/datum/artifact_effect/vampire/DoEffectPulse()
+ DoEffectAura()
diff --git a/code/modules/xenoarcheaology/tools/ano_device_battery.dm b/code/modules/xenoarcheaology/tools/ano_device_battery.dm
index 937f5f2927..f32fc5174f 100644
--- a/code/modules/xenoarcheaology/tools/ano_device_battery.dm
+++ b/code/modules/xenoarcheaology/tools/ano_device_battery.dm
@@ -3,12 +3,18 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "anobattery0"
var/datum/artifact_effect/battery_effect
- var/capacity = 300
+ var/capacity = 500
var/stored_charge = 0
var/effect_id = ""
+/obj/item/weapon/anobattery/advanced
+ name = "advanced anomaly battery"
+ capacity = 3000
+
+/*
/obj/item/weapon/anobattery/New()
battery_effect = new()
+*/
/obj/item/weapon/anobattery/proc/UpdateSprite()
var/p = (stored_charge/capacity)*100
@@ -99,28 +105,33 @@
//handle charge
if(world.time - last_activation > interval)
if(inserted_battery.battery_effect.effect == EFFECT_TOUCH)
+ world << "Effect Touch"
if(interval > 0)
//apply the touch effect to the holder
if(holder)
to_chat(holder, "the \icon[src] [src] held by [holder] shudders in your grasp.")
else
src.loc.visible_message("the \icon[src] [src] shudders.")
- inserted_battery.battery_effect.DoEffectTouch(holder)
//consume power
inserted_battery.use_power(energy_consumed_on_touch)
else
//consume power equal to time passed
+ world << world.time - last_process
inserted_battery.use_power(world.time - last_process)
+ inserted_battery.battery_effect.DoEffectTouch(holder)
+
else if(inserted_battery.battery_effect.effect == EFFECT_PULSE)
inserted_battery.battery_effect.chargelevel = inserted_battery.battery_effect.chargelevelmax
//consume power relative to the time the artifact takes to charge and the effect range
- inserted_battery.use_power(inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.chargelevelmax)
+ world << (inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.chargelevelmax) / 2
+ inserted_battery.use_power((inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.chargelevelmax) / 2)
else
//consume power equal to time passed
+ world << world.time - last_process
inserted_battery.use_power(world.time - last_process)
last_activation = world.time
@@ -167,6 +178,7 @@
if(!inserted_battery.battery_effect.activated)
inserted_battery.battery_effect.ToggleActivate(1)
time_end = world.time + duration
+ last_process = world.time
if(href_list["shutdown"])
activated = 0
if(href_list["ejectbattery"])
diff --git a/code/modules/xenoarcheaology/tools/artifact_harvester.dm b/code/modules/xenoarcheaology/tools/artifact_harvester.dm
index 480061f9bb..089c64abc6 100644
--- a/code/modules/xenoarcheaology/tools/artifact_harvester.dm
+++ b/code/modules/xenoarcheaology/tools/artifact_harvester.dm
@@ -156,6 +156,7 @@
//delete it when the ids match to account for duplicate ids having different effects
if(inserted_battery.battery_effect && inserted_battery.stored_charge <= 0)
qdel(inserted_battery.battery_effect)
+ inserted_battery.battery_effect = null
//
var/datum/artifact_effect/source_effect
diff --git a/polaris.dme b/polaris.dme
index 94633ee193..db25ac16da 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -1947,6 +1947,7 @@
#include "code\modules\mob\update_icons.dm"
#include "code\modules\mob\_modifiers\aura.dm"
#include "code\modules\mob\_modifiers\cloning.dm"
+#include "code\modules\mob\_modifiers\feysight.dm"
#include "code\modules\mob\_modifiers\fire.dm"
#include "code\modules\mob\_modifiers\medical.dm"
#include "code\modules\mob\_modifiers\modifiers.dm"
@@ -2788,12 +2789,16 @@
#include "code\modules\xenoarcheaology\effects\animate_anomaly.dm"
#include "code\modules\xenoarcheaology\effects\badfeeling.dm"
#include "code\modules\xenoarcheaology\effects\berserk.dm"
+#include "code\modules\xenoarcheaology\effects\cannibal.dm"
#include "code\modules\xenoarcheaology\effects\cellcharge.dm"
#include "code\modules\xenoarcheaology\effects\celldrain.dm"
#include "code\modules\xenoarcheaology\effects\cold.dm"
#include "code\modules\xenoarcheaology\effects\dnaswitch.dm"
+#include "code\modules\xenoarcheaology\effects\electric_field.dm"
#include "code\modules\xenoarcheaology\effects\emp.dm"
+#include "code\modules\xenoarcheaology\effects\feysight.dm"
#include "code\modules\xenoarcheaology\effects\forcefield.dm"
+#include "code\modules\xenoarcheaology\effects\gaia.dm"
#include "code\modules\xenoarcheaology\effects\gasco2.dm"
#include "code\modules\xenoarcheaology\effects\gasnitro.dm"
#include "code\modules\xenoarcheaology\effects\gasoxy.dm"
@@ -2806,11 +2811,13 @@
#include "code\modules\xenoarcheaology\effects\hurt.dm"
#include "code\modules\xenoarcheaology\effects\poltergeist.dm"
#include "code\modules\xenoarcheaology\effects\radiate.dm"
+#include "code\modules\xenoarcheaology\effects\resurrect.dm"
#include "code\modules\xenoarcheaology\effects\roboheal.dm"
#include "code\modules\xenoarcheaology\effects\robohurt.dm"
#include "code\modules\xenoarcheaology\effects\sleepy.dm"
#include "code\modules\xenoarcheaology\effects\stun.dm"
#include "code\modules\xenoarcheaology\effects\teleport.dm"
+#include "code\modules\xenoarcheaology\effects\vampire.dm"
#include "code\modules\xenoarcheaology\finds\eguns.dm"
#include "code\modules\xenoarcheaology\finds\find_spawning.dm"
#include "code\modules\xenoarcheaology\finds\finds.dm"
@@ -2863,7 +2870,7 @@
#include "code\ZAS\Zone.dm"
#include "interface\interface.dm"
#include "interface\skin.dmf"
-#include "maps\example\example.dm"
+#include "maps\southern_cross\southern_cross.dm"
#include "maps\submaps\space_submaps\space.dm"
#include "maps\submaps\surface_submaps\mountains\mountains.dm"
#include "maps\submaps\surface_submaps\mountains\mountains_areas.dm"