Merge pull request #3715 from CHOMPStation2/upstream-merge-12285

[MIRROR] 7914 branch fix
This commit is contained in:
Nadyr
2022-02-19 19:58:40 -05:00
committed by GitHub
57 changed files with 1035 additions and 487 deletions

View File

@@ -58,8 +58,8 @@
#define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE "atom_init_success"
///from base of atom/attackby(): (/obj/item, /mob/living, params)
#define COMSIG_PARENT_ATTACKBY "atom_attackby"
///Return this in response if you don't want afterattack to be called
#define COMPONENT_NO_AFTERATTACK (1<<0)
///Return this in response if you don't want later item attack procs to be called.
#define COMPONENT_CANCEL_ATTACK_CHAIN (1<<0)
///from base of atom/attack_hulk(): (/mob/living/carbon/human)
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack"
///from base of atom/animal_attack(): (/mob/user)
@@ -94,6 +94,7 @@
#define COMSIG_ATOM_BUMPED "atom_bumped"
///from base of atom/ex_act(): (severity, target)
#define COMSIG_ATOM_EX_ACT "atom_ex_act"
#define COMPONENT_IGNORE_EXPLOSION (1<<0)
///from base of atom/emp_act(): (severity)
#define COMSIG_ATOM_EMP_ACT "atom_emp_act"
///from base of atom/fire_act(): (exposed_temperature, exposed_volume)
@@ -225,7 +226,7 @@
// /atom/movable signals
///from base of atom/movable/Moved(): (/atom)
///from base of atom/movable/Move(): (atom/newloc, dir, movetime)
#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move"
#define COMPONENT_MOVABLE_BLOCK_PRE_MOVE (1<<0)
///from base of atom/movable/Moved(): (/atom, dir)
@@ -778,3 +779,5 @@
#define COMSIG_CONFLICT_ELEMENT_CHECK "conflict_element_check"
/// A conflict was found
#define ELEMENT_CONFLICT_FOUND (1<<0)
//From reagents touch_x.
#define COMSIG_REAGENTS_TOUCH "reagent_touch"

View File

@@ -25,28 +25,48 @@ avoid code duplication. This includes items that may sometimes act as a standard
return
return
// Called at the start of resolve_attackby(), before the actual attack.
/obj/item/proc/pre_attack(atom/a, mob/user)
return
/**
* Called at the start of resolve_attackby(), before the actual attack.
*
* Arguments:
* * atom/A - The atom about to be hit
* * mob/living/user - The mob doing the htting
* * params - click params such as alt/shift etc
*
* See: [/obj/item/proc/melee_attack_chain]
*/
/obj/item/proc/pre_attack(atom/A, mob/user, params) //do stuff before attackby!
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_CANCEL_ATTACK_CHAIN)
return TRUE
return FALSE //return TRUE to avoid calling attackby after this proc does stuff
//I would prefer to rename this to attack(), but that would involve touching hundreds of files.
/obj/item/proc/resolve_attackby(atom/A, mob/user, var/attack_modifier = 1, var/click_parameters)
pre_attack(A, user)
add_fingerprint(user)
. = pre_attack(A, user, click_parameters)
if(.) // We're returning the value of pre_attack, important if it has a special return.
return
return A.attackby(src, user, attack_modifier, click_parameters)
// No comment
/atom/proc/attackby(obj/item/W, mob/user, var/attack_modifier, var/click_parameters)
if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, click_parameters) & COMPONENT_NO_AFTERATTACK)
if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, click_parameters) & COMPONENT_CANCEL_ATTACK_CHAIN)
return TRUE
return FALSE
/mob/living/attackby(obj/item/I, mob/user, var/attack_modifier, var/click_parameters)
if(!ismob(user))
return 0
if(can_operate(src) && I.do_surgery(src,user))
return 1
return FALSE
if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, I, user, click_parameters) & COMPONENT_CANCEL_ATTACK_CHAIN)
return FALSE
if(can_operate(src, user) && I.do_surgery(src,user))
return TRUE
if(attempt_vr(src,"vore_attackby",args)) return //VOREStation Add - The vore, of course.
return I.attack(src, user, user.zone_sel.selecting, attack_modifier)
// Used to get how fast a mob should attack, and influences click delay.

View File

@@ -26,7 +26,9 @@
A.attack_hand(src)
/atom/proc/attack_hand(mob/user as mob)
return
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_CANCEL_ATTACK_CHAIN)
return TRUE
return FALSE
/mob/living/carbon/human/RestrainedClickOn(var/atom/A)
return

View File

@@ -115,7 +115,7 @@
if(!(mat_container_flags & MATCONTAINER_SILENT))
to_chat(user, "<span class='warning'>[parent] won't accept [I]!</span>")
return
. = COMPONENT_NO_AFTERATTACK
. = COMPONENT_CANCEL_ATTACK_CHAIN
var/datum/callback/pc = precondition
if(pc && !pc.Invoke(user))
return

View File

@@ -125,6 +125,8 @@
/atom/proc/Bumped(AM as mob|obj)
set waitfor = FALSE
SEND_SIGNAL(src, COMSIG_ATOM_BUMPED, AM)
// Convenience proc to see if a container is open for chemistry handling
// returns true if open
// false if closed
@@ -166,6 +168,9 @@
return
/atom/proc/bullet_act(obj/item/projectile/P, def_zone)
if(SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone) & COMPONENT_CANCEL_ATTACK_CHAIN)
return
P.on_hit(src, 0, def_zone)
. = 0
@@ -260,8 +265,8 @@
invisibility = new_invisibility
return TRUE
/atom/proc/ex_act()
return
/atom/proc/ex_act(var/strength = 3)
return (SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, strength, src) & COMPONENT_IGNORE_EXPLOSION)
/atom/proc/emag_act(var/remaining_charges, var/mob/user, var/emag_source)
return -1

View File

@@ -87,6 +87,9 @@
if(!loc || !newloc)
return FALSE
if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_MOVE, newloc, direct, movetime) & COMPONENT_MOVABLE_BLOCK_PRE_MOVE)
return FALSE
// Store this early before we might move, it's used several places
var/atom/oldloc = loc
@@ -234,6 +237,9 @@
riding_datum.handle_vehicle_offsets()
for (var/datum/light_source/light as anything in light_sources) // Cycle through the light sources on this atom and tell them to update.
light.source_atom.update_light()
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, old_loc, direction)
return TRUE
/atom/movable/set_dir(newdir)
@@ -267,6 +273,9 @@
throwing = 0
if(QDELETED(A))
return
SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A)
A.Bumped(src)
A.last_bumped = world.time

View File

@@ -48,12 +48,15 @@
// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing.
/datum/reagent/proc/touch_mob(var/mob/M, var/amount)
SEND_SIGNAL(M, COMSIG_REAGENTS_TOUCH, src, amount)
return
/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc
SEND_SIGNAL(O, COMSIG_REAGENTS_TOUCH, src, amount)
return
/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here
SEND_SIGNAL(T, COMSIG_REAGENTS_TOUCH, src, amount)
return
/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob.

View File

@@ -31,6 +31,9 @@
/datum/reagent/blood/touch_turf(var/turf/simulated/T)
if(!istype(T) || volume < 3)
return
..()
if(!data["donor"] || istype(data["donor"], /mob/living/carbon/human))
blood_splatter(T, src, 1)
else if(istype(data["donor"], /mob/living/carbon/alien))
@@ -169,6 +172,8 @@
if(!istype(T))
return
..()
var/datum/gas_mixture/environment = T.return_air()
var/min_temperature = T0C + 100 // 100C, the boiling point of water
@@ -190,14 +195,19 @@
T.wet_floor(1)
/datum/reagent/water/touch_obj(var/obj/O, var/amount)
..()
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube))
var/obj/item/weapon/reagent_containers/food/snacks/monkeycube/cube = O
if(!cube.wrapped)
cube.Expand()
else if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/cube))
var/obj/item/weapon/reagent_containers/food/snacks/cube/cube = O
cube.Expand()
else
O.water_act(amount / 5)
/datum/reagent/water/touch_mob(var/mob/living/L, var/amount)
..()
if(istype(L))
// First, kill slimes.
if(istype(L, /mob/living/simple_mob/slime))
@@ -252,6 +262,7 @@
glass_desc = "Unless you are an industrial tool, this is probably not safe for consumption."
/datum/reagent/fuel/touch_turf(var/turf/T, var/amount)
..()
new /obj/effect/decal/cleanable/liquid_fuel(T, amount, FALSE)
remove_self(amount)
return
@@ -261,5 +272,6 @@
M.adjustToxLoss(4 * removed)
/datum/reagent/fuel/touch_mob(var/mob/living/L, var/amount)
..()
if(istype(L))
L.adjust_fire_stacks(amount / 10) // Splashing people with welding fuel to make them easy to ignite!

View File

@@ -49,6 +49,7 @@
M.ingested.remove_reagent(R.id, removed * effect)
/datum/reagent/carbon/touch_turf(var/turf/T)
..()
if(!istype(T, /turf/space))
var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt, T)
if (!dirtoverlay)
@@ -106,6 +107,7 @@
allergen_factor = 0.5 //simulates mixed drinks containing less of the allergen, as they have only a single actual reagent unlike food
/datum/reagent/ethanol/touch_mob(var/mob/living/L, var/amount)
..()
if(istype(L))
L.adjust_fire_stacks(amount / 15)
@@ -199,6 +201,7 @@
M.hallucination = max(M.hallucination, halluci)
/datum/reagent/ethanol/touch_obj(var/obj/O)
..()
if(istype(O, /obj/item/weapon/paper))
var/obj/item/weapon/paper/paperaffected = O
paperaffected.clearpaper()
@@ -342,6 +345,7 @@
M.adjustToxLoss(100)
/datum/reagent/radium/touch_turf(var/turf/T)
..()
if(volume >= 3)
if(!istype(T, /turf/space))
var/obj/effect/decal/cleanable/greenglow/glow = locate(/obj/effect/decal/cleanable/greenglow, T)
@@ -430,6 +434,7 @@
M.take_organ_damage(0, removed * power * 0.1) // Balance. The damage is instant, so it's weaker. 10 units -> 5 damage, double for pacid. 120 units beaker could deal 60, but a) it's burn, which is not as dangerous, b) it's a one-use weapon, c) missing with it will splash it over the ground and d) clothes give some protection, so not everything will hit
/datum/reagent/acid/touch_obj(var/obj/O)
..()
if(O.unacidable)
return
if((istype(O, /obj/item) || istype(O, /obj/effect/plant)) && (volume > meltdose))

View File

@@ -170,6 +170,8 @@
if(!istype(T))
return
..()
var/hotspot = (locate(/obj/fire) in T)
if(hotspot && !istype(T, /turf/space))
var/datum/gas_mixture/lowertemp = T.remove_air(T:air:total_moles)
@@ -386,6 +388,7 @@
allergen_type = ALLERGEN_GRAINS //Flour is made from grain
/datum/reagent/nutriment/flour/touch_turf(var/turf/simulated/T)
..()
if(!istype(T, /turf/space))
new /obj/effect/decal/cleanable/flour(T)
@@ -565,6 +568,7 @@
glass_desc = "Durian paste. It smells horrific."
/datum/reagent/nutriment/durian/touch_mob(var/mob/M, var/amount)
..()
if(iscarbon(M) && !M.isSynthetic())
var/message = pick("Oh god, it smells disgusting here.", "What is that stench?", "That's an awful odor.")
to_chat(M, "<span class='alien'>[message]</span>")
@@ -574,6 +578,7 @@
return ..()
/datum/reagent/nutriment/durian/touch_turf(var/turf/T, var/amount)
..()
if(istype(T))
var/obj/effect/decal/cleanable/chemcoating/C = new /obj/effect/decal/cleanable/chemcoating(T)
C.reagents.add_reagent(id, amount)

View File

@@ -346,6 +346,7 @@
M.adjustToxLoss(3 * removed)
/datum/reagent/tricorlidaze/touch_obj(var/obj/O)
..()
if(istype(O, /obj/item/stack/medical/bruise_pack) && round(volume) >= 5)
var/obj/item/stack/medical/bruise_pack/C = O
var/packname = C.name
@@ -1281,6 +1282,7 @@
M.add_chemical_effect(CE_PAINKILLER, 20 * M.species.chem_strength_pain) // 5 less than paracetamol.
/datum/reagent/spacomycaze/touch_obj(var/obj/O)
..()
if(istype(O, /obj/item/stack/medical/crude_pack) && round(volume) >= 1)
var/obj/item/stack/medical/crude_pack/C = O
var/packname = C.name
@@ -1317,10 +1319,12 @@
M.adjustToxLoss(2 * removed)
/datum/reagent/sterilizine/touch_obj(var/obj/O)
..()
O.germ_level -= min(volume*20, O.germ_level)
O.was_bloodied = null
/datum/reagent/sterilizine/touch_turf(var/turf/T)
..()
T.germ_level -= min(volume*20, T.germ_level)
for(var/obj/item/I in T.contents)
I.was_bloodied = null
@@ -1334,6 +1338,7 @@
//VOREstation edit end
/datum/reagent/sterilizine/touch_mob(var/mob/living/L, var/amount)
..()
if(istype(L))
if(istype(L, /mob/living/simple_mob/slime))
var/mob/living/simple_mob/slime/S = L

View File

@@ -42,6 +42,7 @@
affect_blood(M, alien, removed * 0.6)
/datum/reagent/modapplying/cryofluid/touch_mob(var/mob/M, var/amount)
..()
if(isliving(M))
var/mob/living/L = M
for(var/I = 1 to rand(1, round(amount + 1)))
@@ -49,6 +50,7 @@
return
/datum/reagent/modapplying/cryofluid/touch_turf(var/turf/T, var/amount)
..()
if(istype(T, /turf/simulated/floor/water) && prob(amount))
T.visible_message("<span class='danger'>\The [T] crackles loudly as the cryogenic fluid causes it to boil away, leaving behind a hard layer of ice.</span>")
T.ChangeTurf(/turf/simulated/floor/outdoors/ice, 1, 1, TRUE)

View File

@@ -114,14 +114,17 @@
color_weight = 20
/datum/reagent/paint/touch_turf(var/turf/T)
..()
if(istype(T) && !istype(T, /turf/space))
T.color = color
/datum/reagent/paint/touch_obj(var/obj/O)
..()
if(istype(O))
O.color = color
/datum/reagent/paint/touch_mob(var/mob/M)
..()
if(istype(M) && !istype(M, /mob/observer)) //painting ghosts: not allowed
M.color = color //maybe someday change this to paint only clothes and exposed body parts for human mobs.
@@ -267,6 +270,7 @@
M.apply_effect(5 * removed, IRRADIATE, 0)
/datum/reagent/uranium/touch_turf(var/turf/T)
..()
if(volume >= 3)
if(!istype(T, /turf/space))
var/obj/effect/decal/cleanable/greenglow/glow = locate(/obj/effect/decal/cleanable/greenglow, T)
@@ -361,6 +365,7 @@
cult.remove_antagonist(M.mind)
/datum/reagent/water/holywater/touch_turf(var/turf/T)
..()
if(volume >= 5)
T.holy = 1
return
@@ -408,6 +413,7 @@
touch_met = 50
/datum/reagent/thermite/touch_turf(var/turf/T)
..()
if(volume >= 5)
if(istype(T, /turf/simulated/wall))
var/turf/simulated/wall/W = T
@@ -417,6 +423,7 @@
return
/datum/reagent/thermite/touch_mob(var/mob/living/L, var/amount)
..()
if(istype(L))
L.adjust_fire_stacks(amount / 5)
@@ -433,14 +440,17 @@
touch_met = 50
/datum/reagent/space_cleaner/touch_mob(var/mob/M)
..()
if(iscarbon(M))
var/mob/living/carbon/C = M
C.clean_blood()
/datum/reagent/space_cleaner/touch_obj(var/obj/O)
..()
O.clean_blood()
/datum/reagent/space_cleaner/touch_turf(var/turf/T)
..()
if(volume >= 1)
if(istype(T, /turf/simulated))
var/turf/simulated/S = T
@@ -488,6 +498,7 @@
M.vomit()
/datum/reagent/space_cleaner/touch_mob(var/mob/living/L, var/amount)
..()
if(istype(L, /mob/living/carbon/human))
var/mob/living/carbon/human/H = L
if(H.wear_mask)
@@ -506,6 +517,7 @@
color = "#009CA8"
/datum/reagent/lube/touch_turf(var/turf/simulated/T)
..()
if(!istype(T))
return
if(volume >= 1)
@@ -520,6 +532,7 @@
color = "#C7FFFF"
/datum/reagent/silicate/touch_obj(var/obj/O)
..()
if(istype(O, /obj/structure/window))
var/obj/structure/window/W = O
W.apply_silicate(volume)
@@ -593,9 +606,11 @@
color = "#F2F3F4"
/datum/reagent/luminol/touch_obj(var/obj/O)
..()
O.reveal_blood()
/datum/reagent/luminol/touch_mob(var/mob/living/L)
..()
L.reveal_blood()
/datum/reagent/nutriment/biomass

View File

@@ -96,6 +96,7 @@
var/fire_mult = 30
/datum/reagent/toxin/hydrophoron/touch_mob(var/mob/living/L, var/amount)
..()
if(istype(L))
L.adjust_fire_stacks(amount / fire_mult)
@@ -107,6 +108,7 @@
/datum/reagent/toxin/hydrophoron/touch_turf(var/turf/simulated/T)
if(!istype(T))
return
..()
T.assume_gas("phoron", CEILING(volume/2, 1), T20C)
for(var/turf/simulated/floor/target_tile in range(0,T))
target_tile.assume_gas("phoron", volume/2, 400+T0C)
@@ -148,6 +150,7 @@
skin_danger = 1
/datum/reagent/toxin/phoron/touch_mob(var/mob/living/L, var/amount)
..()
if(istype(L))
L.adjust_fire_stacks(amount / 5)
@@ -169,6 +172,7 @@
..()
/datum/reagent/toxin/phoron/touch_turf(var/turf/simulated/T, var/amount)
..()
if(!istype(T))
return
T.assume_gas("volatile_fuel", amount, T20C)
@@ -390,6 +394,7 @@
color = "#e67819"
/datum/reagent/toxin/fertilizer/tannin/touch_obj(var/obj/O, var/volume)
..()
if(istype(O, /obj/item/stack/hairlesshide))
var/obj/item/stack/hairlesshide/HH = O
HH.rapidcure(round(volume))
@@ -405,6 +410,7 @@
strength = 4
/datum/reagent/toxin/plantbgone/touch_turf(var/turf/T)
..()
if(istype(T, /turf/simulated/wall))
var/turf/simulated/wall/W = T
if(locate(/obj/effect/overlay/wallrot) in W)
@@ -413,6 +419,7 @@
W.visible_message("<span class='notice'>The fungi are completely dissolved by the solution!</span>")
/datum/reagent/toxin/plantbgone/touch_obj(var/obj/O, var/volume)
..()
if(istype(O, /obj/effect/plant))
qdel(O)
else if(istype(O, /obj/effect/alien/weeds/))

View File

@@ -14,6 +14,15 @@
if(A)
contain(A)
else
for(var/obj/Ob in loc)
if(can_contain(Ob))
contain(Ob)
break
/obj/structure/anomaly_container/proc/can_contain(var/obj/O)
return O.is_anomalous()
/obj/structure/anomaly_container/attack_hand(var/mob/user)
release()
@@ -37,7 +46,11 @@
underlays.Cut()
desc = initial(desc)
/obj/machinery/artifact/MouseDrop(var/obj/structure/anomaly_container/over_object)
if(istype(over_object) && Adjacent(over_object) && CanMouseDrop(over_object, usr))
/atom/MouseDrop(var/obj/structure/anomaly_container/over_object)
. = ..()
if(istype(over_object))
if(!QDELETED(src) && istype(loc, /turf) && is_anomalous() && Adjacent(over_object) && CanMouseDrop(over_object, usr))
Bumped(usr)
over_object.contain(src)

View File

@@ -5,42 +5,25 @@
icon_state = "ano00"
var/icon_num = 0
density = TRUE
var/datum/artifact_effect/my_effect
var/datum/artifact_effect/secondary_effect
var/being_used = 0
var/predefined_effects = FALSE
var/predefined_primary
var/predefined_secondary
var/predefined_icon_num
var/predefined_triggers = FALSE
var/datum/component/artifact_master/artifact_master = /datum/component/artifact_master
var/predefined_trig_primary
var/predefined_trig_secondary
var/being_used = 0
/obj/machinery/artifact/New()
..()
if(predefined_effects && predefined_primary)
my_effect = new predefined_primary(src)
if(ispath(artifact_master))
AddComponent(artifact_master)
if(predefined_secondary)
secondary_effect = new predefined_secondary(src)
if(prob(75))
secondary_effect.ToggleActivate(0)
artifact_master = GetComponent(artifact_master)
else
var/effecttype = pick(subtypesof(/datum/artifact_effect))
my_effect = new effecttype(src)
if(!istype(artifact_master))
return
if(prob(75))
effecttype = pick(subtypesof(/datum/artifact_effect))
secondary_effect = new effecttype(src)
if(prob(75))
secondary_effect.ToggleActivate(0)
var/datum/artifact_effect/my_effect = artifact_master.get_primary()
if(!isnull(predefined_icon_num))
icon_num = predefined_icon_num
@@ -77,299 +60,10 @@
if(prob(60))
my_effect.trigger = pick(TRIGGER_TOUCH, TRIGGER_HEAT, TRIGGER_COLD, TRIGGER_PHORON, TRIGGER_OXY, TRIGGER_CO2, TRIGGER_NITRO)
if(predefined_triggers)
if(predefined_trig_primary && my_effect)
my_effect.trigger = predefined_trig_primary
if(predefined_trig_secondary && secondary_effect)
secondary_effect.trigger = predefined_trig_secondary
/obj/machinery/artifact/proc/choose_effect()
var/effect_type = tgui_input_list(usr, "What type do you want?", "Effect Type", subtypesof(/datum/artifact_effect))
if(effect_type)
my_effect = new effect_type(src)
if(tgui_alert(usr, "Do you want a secondary effect?", "Second Effect", list("No", "Yes")) == "Yes")
var/second_effect_type = tgui_input_list(usr, "What type do you want as well?", "Second Effect Type", subtypesof(/datum/artifact_effect) - effect_type)
secondary_effect = new second_effect_type(src)
else
secondary_effect = null
/obj/machinery/artifact/process()
var/turf/L = loc
if(!istype(L)) // We're inside a container or on null turf, either way stop processing effects
return
if(my_effect)
my_effect.process()
if(secondary_effect)
secondary_effect.process()
if(pulledby)
Bumped(pulledby)
//if either of our effects rely on environmental factors, work that out
var/trigger_cold = 0
var/trigger_hot = 0
var/trigger_phoron = 0
var/trigger_oxy = 0
var/trigger_co2 = 0
var/trigger_nitro = 0
if( (my_effect.trigger >= TRIGGER_HEAT && my_effect.trigger <= TRIGGER_NITRO) || (my_effect.trigger >= TRIGGER_HEAT && my_effect.trigger <= TRIGGER_NITRO) )
var/turf/T = get_turf(src)
var/datum/gas_mixture/env = T.return_air()
if(env)
if(env.temperature < 225)
trigger_cold = 1
else if(env.temperature > 375)
trigger_hot = 1
if(env.gas["phoron"] >= 10)
trigger_phoron = 1
if(env.gas["oxygen"] >= 10)
trigger_oxy = 1
if(env.gas["carbon_dioxide"] >= 10)
trigger_co2 = 1
if(env.gas["nitrogen"] >= 10)
trigger_nitro = 1
//COLD ACTIVATION
if(trigger_cold)
if(my_effect.trigger == TRIGGER_COLD && !my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_COLD && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
else
if(my_effect.trigger == TRIGGER_COLD && my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_COLD && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
//HEAT ACTIVATION
if(trigger_hot)
if(my_effect.trigger == TRIGGER_HEAT && !my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_HEAT && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
else
if(my_effect.trigger == TRIGGER_HEAT && my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_HEAT && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
//PHORON GAS ACTIVATION
if(trigger_phoron)
if(my_effect.trigger == TRIGGER_PHORON && !my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_PHORON && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
else
if(my_effect.trigger == TRIGGER_PHORON && my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_PHORON && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
//OXYGEN GAS ACTIVATION
if(trigger_oxy)
if(my_effect.trigger == TRIGGER_OXY && !my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_OXY && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
else
if(my_effect.trigger == TRIGGER_OXY && my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_OXY && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
//CO2 GAS ACTIVATION
if(trigger_co2)
if(my_effect.trigger == TRIGGER_CO2 && !my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_CO2 && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
else
if(my_effect.trigger == TRIGGER_CO2 && my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_CO2 && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
//NITROGEN GAS ACTIVATION
if(trigger_nitro)
if(my_effect.trigger == TRIGGER_NITRO && !my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_NITRO && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
else
if(my_effect.trigger == TRIGGER_NITRO && my_effect.activated)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_NITRO && !secondary_effect.activated)
secondary_effect.ToggleActivate(0)
/obj/machinery/artifact/attack_hand(var/mob/user as mob)
if (get_dist(user, src) > 1)
to_chat(user, "<font color='red'>You can't reach [src] from here.</font>")
return
if(ishuman(user) && user:gloves)
to_chat(user, "<b>You touch [src]</b> with your gloved hands, [pick("but nothing of note happens","but nothing happens","but nothing interesting happens","but you notice nothing different","but nothing seems to have happened")].")
return
src.add_fingerprint(user)
if(my_effect.trigger == TRIGGER_TOUCH)
to_chat(user, "<b>You touch [src].</b>")
my_effect.ToggleActivate()
else
to_chat(user, "<b>You touch [src],</b> [pick("but nothing of note happens","but nothing happens","but nothing interesting happens","but you notice nothing different","but nothing seems to have happened")].")
if(prob(25) && secondary_effect && secondary_effect.trigger == TRIGGER_TOUCH)
secondary_effect.ToggleActivate(0)
if (my_effect.effect == EFFECT_TOUCH)
my_effect.DoEffectTouch(user)
if(secondary_effect && secondary_effect.effect == EFFECT_TOUCH && secondary_effect.activated)
secondary_effect.DoEffectTouch(user)
/obj/machinery/artifact/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
if (istype(W, /obj/item/weapon/reagent_containers/))
if(W.reagents.has_reagent("hydrogen", 1) || W.reagents.has_reagent("water", 1))
if(my_effect.trigger == TRIGGER_WATER)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_WATER && prob(25))
secondary_effect.ToggleActivate(0)
else if(W.reagents.has_reagent("sacid", 1) || W.reagents.has_reagent("pacid", 1) || W.reagents.has_reagent("diethylamine", 1))
if(my_effect.trigger == TRIGGER_ACID)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_ACID && prob(25))
secondary_effect.ToggleActivate(0)
else if(W.reagents.has_reagent("phoron", 1) || W.reagents.has_reagent("thermite", 1))
if(my_effect.trigger == TRIGGER_VOLATILE)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_VOLATILE && prob(25))
secondary_effect.ToggleActivate(0)
else if(W.reagents.has_reagent("toxin", 1) || W.reagents.has_reagent("cyanide", 1) || W.reagents.has_reagent("amatoxin", 1) || W.reagents.has_reagent("neurotoxin", 1))
if(my_effect.trigger == TRIGGER_TOXIN)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_TOXIN && prob(25))
secondary_effect.ToggleActivate(0)
else if(istype(W,/obj/item/weapon/melee/baton) && W:status ||\
istype(W,/obj/item/weapon/melee/energy) ||\
istype(W,/obj/item/weapon/melee/cultblade) ||\
istype(W,/obj/item/weapon/card/emag) ||\
istype(W,/obj/item/device/multitool))
if (my_effect.trigger == TRIGGER_ENERGY)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_ENERGY && prob(25))
secondary_effect.ToggleActivate(0)
else if (istype(W,/obj/item/weapon/flame) && W:lit ||\
istype(W,/obj/item/weapon/weldingtool) && W:welding)
if(my_effect.trigger == TRIGGER_HEAT)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_HEAT && prob(25))
secondary_effect.ToggleActivate(0)
else
..()
if (my_effect.trigger == TRIGGER_FORCE && W.force >= 10)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
secondary_effect.ToggleActivate(0)
/obj/machinery/artifact/Bumped(M as mob|obj)
..()
if(istype(M,/obj))
if(M:throwforce >= 10)
if(my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
secondary_effect.ToggleActivate(0)
else if(ishuman(M) && !istype(M:gloves,/obj/item/clothing/gloves))
var/warn = 0
if (my_effect.trigger == TRIGGER_TOUCH && prob(50))
my_effect.ToggleActivate()
warn = 1
if(secondary_effect && secondary_effect.trigger == TRIGGER_TOUCH && prob(25))
secondary_effect.ToggleActivate(0)
warn = 1
if (my_effect.effect == EFFECT_TOUCH && prob(50))
my_effect.DoEffectTouch(M)
warn = 1
if(secondary_effect && secondary_effect.effect == EFFECT_TOUCH && secondary_effect.activated && prob(50))
secondary_effect.DoEffectTouch(M)
warn = 1
if(warn)
to_chat(M, "<b>You accidentally touch \the [src].</b>")
/obj/machinery/artifact/update_icon()
..()
/obj/machinery/artifact/Bump(var/atom/bumped)
if(istype(bumped,/obj))
if(bumped:throwforce >= 10)
if(my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
secondary_effect.ToggleActivate(0)
else if(ishuman(bumped) && GetAnomalySusceptibility(bumped) >= 0.5)
var/warn = 0
if (my_effect.trigger == TRIGGER_TOUCH && prob(50))
my_effect.ToggleActivate()
warn = 1
if(secondary_effect && secondary_effect.trigger == TRIGGER_TOUCH && prob(25))
secondary_effect.ToggleActivate(0)
warn = 1
if (my_effect.effect == EFFECT_TOUCH && prob(50))
my_effect.DoEffectTouch(bumped)
warn = 1
if(secondary_effect && secondary_effect.effect == EFFECT_TOUCH && secondary_effect.activated && prob(50))
secondary_effect.DoEffectTouch(bumped)
warn = 1
if(warn)
to_chat(bumped, "<b>You accidentally touch \the [src] as it hits you.</b>")
..()
/obj/machinery/artifact/bullet_act(var/obj/item/projectile/P)
if(istype(P,/obj/item/projectile/bullet))
if(my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
secondary_effect.ToggleActivate(0)
else if(istype(P,/obj/item/projectile/beam) ||\
istype(P,/obj/item/projectile/ion) ||\
istype(P,/obj/item/projectile/energy))
if(my_effect.trigger == TRIGGER_ENERGY)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_ENERGY && prob(25))
secondary_effect.ToggleActivate(0)
/obj/machinery/artifact/ex_act(severity)
switch(severity)
if(1.0) qdel(src)
if(2.0)
if (prob(50))
qdel(src)
if(LAZYLEN(artifact_master.get_active_effects()))
icon_state = "ano[icon_num]1"
else
if(my_effect.trigger == TRIGGER_FORCE || my_effect.trigger == TRIGGER_HEAT)
my_effect.ToggleActivate()
if(secondary_effect && (secondary_effect.trigger == TRIGGER_FORCE || secondary_effect.trigger == TRIGGER_HEAT) && prob(25))
secondary_effect.ToggleActivate(0)
if(3.0)
if (my_effect.trigger == TRIGGER_FORCE || my_effect.trigger == TRIGGER_HEAT)
my_effect.ToggleActivate()
if(secondary_effect && (secondary_effect.trigger == TRIGGER_FORCE || secondary_effect.trigger == TRIGGER_HEAT) && prob(25))
secondary_effect.ToggleActivate(0)
return
/obj/machinery/artifact/Moved()
. = ..()
if(my_effect)
my_effect.UpdateMove()
if(secondary_effect)
secondary_effect.UpdateMove()
icon_state = "ano[icon_num]0"

View File

@@ -1,15 +1,3 @@
/obj/machinery/artifact/predefined
name = "alien artifact"
desc = "A large alien device."
predefined_effects = TRUE
predefined_primary = null
predefined_secondary = null
predefined_icon_num = null
predefined_triggers = FALSE
predefined_trig_primary = null
predefined_trig_secondary = null

View File

@@ -2,14 +2,12 @@
name = "alien artifact"
desc = "A large alien device."
predefined_effects = TRUE
predefined_primary = /datum/artifact_effect/animate_anomaly
predefined_secondary = /datum/artifact_effect/vampire
artifact_master = /datum/component/artifact_master/hungry_statue
predefined_icon_num = 14
predefined_triggers = TRUE
predefined_trig_primary = TRIGGER_OXY
predefined_trig_secondary = TRIGGER_OXY
/datum/component/artifact_master/hungry_statue
make_effects = list(
/datum/artifact_effect/animate_anomaly,
/datum/artifact_effect/vampire
)

View File

@@ -75,8 +75,8 @@
var/obj/O = new spawn_type(get_turf(src))
if(istype(O, /obj/machinery/artifact))
var/obj/machinery/artifact/X = O
if(X.my_effect)
X.my_effect.artifact_id = artifact_find.artifact_id
if(X.artifact_master)
X.artifact_master.artifact_id = artifact_find.artifact_id
O.anchored = FALSE // Anchored finds are lame.
src.visible_message("<span class='warning'>\The [src] suddenly crumbles away.</span>")
else

View File

@@ -3,19 +3,47 @@
var/effect = EFFECT_TOUCH
var/effectrange = 4
var/trigger = TRIGGER_TOUCH
var/atom/holder
var/datum/component/artifact_master/master
var/activated = 0
var/chargelevel = 0
var/chargelevel = 1
var/chargelevelmax = 10
var/artifact_id = ""
var/effect_type = 0
/datum/artifact_effect/New(var/atom/location)
var/req_type = /atom/movable
var/image/active_effect
var/effect_icon = 'icons/effects/effects.dmi'
var/effect_state = "sparkles"
var/effect_color = "#ffffff"
// The last time the effect was toggled.
var/last_activation = 0
/datum/artifact_effect/Destroy()
if(master)
master = null
..()
holder = location
/datum/artifact_effect/proc/get_master_holder() // Return the effectmaster's holder, if it is set to an effectmaster. Otherwise, master is the target object.
if(istype(master))
return master.holder
else
return master
/datum/artifact_effect/New(var/datum/component/artifact_master/newmaster)
..()
master = newmaster
effect = rand(0, MAX_EFFECT)
trigger = rand(0, MAX_TRIGGER)
if(effect_icon && effect_state)
if(effect_state == "sparkles")
effect_state = "sparkles_[rand(1,4)]"
active_effect = image(effect_icon, effect_state)
active_effect.color = effect_color
//this will be replaced by the excavation code later, but it's here just in case
artifact_id = "[pick("kappa","sigma","antaeres","beta","omicron","iota","epsilon","omega","gamma","delta","tau","alpha")]-[rand(100,999)]"
@@ -36,21 +64,32 @@
/datum/artifact_effect/proc/ToggleActivate(var/reveal_toggle = 1)
//so that other stuff happens first
spawn(0)
set waitfor = FALSE
var/atom/target = get_master_holder()
if(world.time - last_activation > 1 SECOND)
last_activation = world.time
if(activated)
activated = 0
else
activated = 1
if(reveal_toggle && holder)
if(istype(holder, /obj/machinery/artifact))
var/obj/machinery/artifact/A = holder
A.icon_state = "ano[A.icon_num][activated]"
if(reveal_toggle && target)
if(!isliving(target))
target.update_icon()
var/display_msg
if(activated)
display_msg = pick("momentarily glows brightly!","distorts slightly for a moment!","flickers slightly!","vibrates!","shimmers slightly for a moment!")
else
display_msg = pick("grows dull!","fades in intensity!","suddenly becomes very still!","suddenly becomes very quiet!")
var/atom/toplevelholder = holder
if(active_effect)
if(activated)
target.underlays.Add(active_effect)
else
target.underlays.Remove(active_effect)
var/atom/toplevelholder = target
while(!istype(toplevelholder.loc, /turf))
toplevelholder = toplevelholder.loc
toplevelholder.visible_message("<font color='red'>[bicon(toplevelholder)] [toplevelholder] [display_msg]</font>")

View File

@@ -0,0 +1,421 @@
/*
* Here there be the base component for artifacts.
*/
/atom/proc/is_anomalous()
return (GetComponent(/datum/component/artifact_master))
/atom/proc/become_anomalous()
if(!is_anomalous())
AddComponent(/datum/component/artifact_master)
if(istype(src, /obj/item))
var/obj/item/I = src
LAZYINITLIST(I.origin_tech)
if(prob(50))
I.origin_tech[TECH_PRECURSOR] += 1
else
I.origin_tech[TECH_ARCANE] += 1
var/rand_tech = pick(\
TECH_MATERIAL,\
TECH_ENGINEERING,\
TECH_PHORON,\
TECH_POWER,\
TECH_BLUESPACE,\
TECH_BIO,\
TECH_COMBAT,\
TECH_MAGNET,\
TECH_DATA,\
TECH_ILLEGAL\
)
LAZYSET(I.origin_tech, rand_tech, rand(4,7))
/datum/component/artifact_master
var/atom/holder
var/list/my_effects
dupe_type = /datum/component/artifact_master
var/effect_generation_chance = 100
var/list/make_effects
var/artifact_id
/datum/component/artifact_master/New()
. = ..()
holder = parent
if(!holder)
qdel(src)
return
my_effects = list()
START_PROCESSING(SSobj, src)
do_setup()
return
/*
* Component System Registry.
* Here be dragons.
*/
/datum/component/artifact_master/proc/DoRegistry()
//Melee Hit
RegisterSignal(holder, COMSIG_PARENT_ATTACKBY, /datum/component/artifact_master/proc/on_attackby, override = FALSE)
//Explosions
RegisterSignal(holder, COMSIG_ATOM_EX_ACT, /datum/component/artifact_master/proc/on_exact, override = FALSE)
//Bullets
RegisterSignal(holder, COMSIG_ATOM_BULLET_ACT, /datum/component/artifact_master/proc/on_bullet, override = FALSE)
//Attackhand
RegisterSignal(holder, COMSIG_ATOM_ATTACK_HAND, /datum/component/artifact_master/proc/on_attack_hand, override = FALSE)
//Bumped / Bumping
RegisterSignal(holder, COMSIG_MOVABLE_BUMP, /datum/component/artifact_master/proc/on_bump, override = FALSE)
RegisterSignal(holder, COMSIG_ATOM_BUMPED, /datum/component/artifact_master/proc/on_bumped, override = FALSE)
//Moved
RegisterSignal(holder, COMSIG_MOVABLE_MOVED, /datum/component/artifact_master/proc/on_moved, override = FALSE)
//Splashed with a reagent.
RegisterSignal(holder, COMSIG_REAGENTS_TOUCH, /datum/component/artifact_master/proc/on_reagent, override = FALSE)
/*
*
*/
/datum/component/artifact_master/proc/get_active_effects()
var/list/active_effects = list()
for(var/datum/artifact_effect/my_effect in my_effects)
if(my_effect.activated)
active_effects |= my_effect
return active_effects
/datum/component/artifact_master/proc/add_effect()
var/effect_type = input(usr, "What type do you want?", "Effect Type") as null|anything in subtypesof(/datum/artifact_effect)
if(effect_type)
var/datum/artifact_effect/my_effect = new effect_type(src)
if(istype(holder, my_effect.req_type))
my_effects += my_effect
else
to_chat(usr, "This effect can not be applied to this atom type.")
qdel(my_effect)
/datum/component/artifact_master/proc/remove_effect()
var/to_remove_effect = input(usr, "What effect do you want to remove?", "Remove Effect") as null|anything in my_effects
if(to_remove_effect)
var/datum/artifact_effect/AE = to_remove_effect
my_effects.Remove(to_remove_effect)
qdel(AE)
/datum/component/artifact_master/Destroy()
holder = null
for(var/datum/artifact_effect/AE in my_effects)
AE.master = null
qdel(AE)
STOP_PROCESSING(SSobj,src)
. = ..()
/datum/component/artifact_master/proc/do_setup()
if(LAZYLEN(make_effects))
for(var/path in make_effects)
var/datum/artifact_effect/new_effect = new path(src)
if(istype(holder, new_effect.req_type))
my_effects += new_effect
else
generate_effects()
DoRegistry()
/datum/component/artifact_master/proc/generate_effects()
while(effect_generation_chance > 0)
var/chosen_path = pick(subtypesof(/datum/artifact_effect))
if(effect_generation_chance >= 100) // If we're above 100 percent, just cut a flat amount and add an effect.
var/datum/artifact_effect/AE = new chosen_path(src)
if(istype(holder, AE.req_type))
my_effects += AE
effect_generation_chance -= 30
else
AE.master = src
qdel(AE)
continue
effect_generation_chance /= 2
if(prob(effect_generation_chance)) // Otherwise, add effects as normal, with decreasing probability.
my_effects += new chosen_path(src)
effect_generation_chance = round(effect_generation_chance)
/datum/component/artifact_master/proc/get_holder() // Returns the holder.
return holder
/datum/component/artifact_master/proc/get_primary()
if(LAZYLEN(my_effects))
return my_effects[1]
return FALSE
/*
* Trigger code.
*/
/datum/component/artifact_master/proc/on_exact()
var/severity = args[2]
var/triggered = FALSE
for(var/datum/artifact_effect/my_effect in my_effects)
switch(severity)
if(1.0)
if(my_effect.trigger == TRIGGER_FORCE || my_effect.trigger == TRIGGER_HEAT || my_effect.trigger == TRIGGER_ENERGY)
my_effect.ToggleActivate()
triggered = TRUE
if(2.0)
if(my_effect.trigger == TRIGGER_FORCE || my_effect.trigger == TRIGGER_HEAT)
my_effect.ToggleActivate()
triggered = TRUE
if(3.0)
if (my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
triggered = TRUE
if(triggered)
return COMPONENT_IGNORE_EXPLOSION
return
/datum/component/artifact_master/proc/on_bullet()
var/obj/item/projectile/P = args[2]
var/triggered = TRUE
for(var/datum/artifact_effect/my_effect in my_effects)
if(istype(P,/obj/item/projectile/bullet))
if(my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
triggered = TRUE
else if(istype(P,/obj/item/projectile/beam) ||\
istype(P,/obj/item/projectile/ion) ||\
istype(P,/obj/item/projectile/energy))
if(my_effect.trigger == TRIGGER_ENERGY)
my_effect.ToggleActivate()
triggered = TRUE
if(triggered)
return COMPONENT_CANCEL_ATTACK_CHAIN
return
/datum/component/artifact_master/proc/on_bump()
var/atom/bumped = args[2]
var/warn = FALSE
for(var/datum/artifact_effect/my_effect in my_effects)
if(istype(bumped,/obj))
if(bumped:throwforce >= 10)
if(my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
else if(ishuman(bumped) && GetAnomalySusceptibility(bumped) >= 0.5)
if (my_effect.trigger == TRIGGER_TOUCH && prob(50))
my_effect.ToggleActivate()
warn = 1
if (my_effect.effect == EFFECT_TOUCH && prob(50))
my_effect.DoEffectTouch(bumped)
warn = 1
if(warn && isliving(bumped))
to_chat(bumped, "<b>You accidentally touch \the [holder] as it hits you.</b>")
/datum/component/artifact_master/proc/on_bumped()
var/atom/movable/M = args[2]
var/warn = FALSE
for(var/datum/artifact_effect/my_effect in my_effects)
if(istype(M,/obj))
if(M:throwforce >= 10)
if(my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
else if(ishuman(M) && !istype(M:gloves,/obj/item/clothing/gloves))
if (my_effect.trigger == TRIGGER_TOUCH && prob(50))
my_effect.ToggleActivate()
warn = 1
if (my_effect.effect == EFFECT_TOUCH && prob(50))
my_effect.DoEffectTouch(M)
warn = 1
if(warn && isliving(M))
to_chat(M, "<b>You accidentally touch \the [holder].</b>")
/datum/component/artifact_master/proc/on_attack_hand()
var/mob/living/user = args[2]
if(!istype(user))
return
if (get_dist(user, holder) > 1)
to_chat(user, "<font color='red'>You can't reach [holder] from here.</font>")
return
if(ishuman(user) && user:gloves)
to_chat(user, "<b>You touch [holder]</b> with your gloved hands, [pick("but nothing of note happens","but nothing happens","but nothing interesting happens","but you notice nothing different","but nothing seems to have happened")].")
return
var/triggered = FALSE
for(var/datum/artifact_effect/my_effect in my_effects)
if(my_effect.trigger == TRIGGER_TOUCH)
triggered = TRUE
my_effect.ToggleActivate()
if (my_effect.effect == EFFECT_TOUCH)
triggered = TRUE
my_effect.DoEffectTouch(user)
if(triggered)
to_chat(user, "<b>You touch [holder].</b>")
else
to_chat(user, "<b>You touch [holder],</b> [pick("but nothing of note happens","but nothing happens","but nothing interesting happens","but you notice nothing different","but nothing seems to have happened")].")
/datum/component/artifact_master/proc/on_attackby()
var/obj/item/weapon/W = args[2]
for(var/datum/artifact_effect/my_effect in my_effects)
if (istype(W, /obj/item/weapon/reagent_containers))
if(W.reagents.has_reagent("hydrogen", 1) || W.reagents.has_reagent("water", 1))
if(my_effect.trigger == TRIGGER_WATER)
my_effect.ToggleActivate()
else if(W.reagents.has_reagent("sacid", 1) || W.reagents.has_reagent("pacid", 1) || W.reagents.has_reagent("diethylamine", 1))
if(my_effect.trigger == TRIGGER_ACID)
my_effect.ToggleActivate()
else if(W.reagents.has_reagent("phoron", 1) || W.reagents.has_reagent("thermite", 1))
if(my_effect.trigger == TRIGGER_VOLATILE)
my_effect.ToggleActivate()
else if(W.reagents.has_reagent("toxin", 1) || W.reagents.has_reagent("cyanide", 1) || W.reagents.has_reagent("amatoxin", 1) || W.reagents.has_reagent("neurotoxin", 1))
if(my_effect.trigger == TRIGGER_TOXIN)
my_effect.ToggleActivate()
else if(istype(W,/obj/item/weapon/melee/baton) && W:status ||\
istype(W,/obj/item/weapon/melee/energy) ||\
istype(W,/obj/item/weapon/melee/cultblade) ||\
istype(W,/obj/item/weapon/card/emag) ||\
istype(W,/obj/item/device/multitool))
if (my_effect.trigger == TRIGGER_ENERGY)
my_effect.ToggleActivate()
else if (istype(W,/obj/item/weapon/flame) && W:lit ||\
istype(W,/obj/item/weapon/weldingtool) && W:welding)
if(my_effect.trigger == TRIGGER_HEAT)
my_effect.ToggleActivate()
else
if (my_effect.trigger == TRIGGER_FORCE && W.force >= 10)
my_effect.ToggleActivate()
/datum/component/artifact_master/proc/on_reagent()
var/datum/reagent/Touching = args[2]
var/list/water = list("hydrogen", "water")
var/list/acid = list("sacid", "pacid", "diethylamine")
var/list/volatile = list("phoron","thermite")
var/list/toxic = list("toxin","cyanide","amatoxin","neurotoxin")
for(var/datum/artifact_effect/my_effect in my_effects)
if(Touching.id in water)
if(my_effect.trigger == TRIGGER_WATER)
my_effect.ToggleActivate()
else if(Touching.id in acid)
if(my_effect.trigger == TRIGGER_ACID)
my_effect.ToggleActivate()
else if(Touching.id in volatile)
if(my_effect.trigger == TRIGGER_VOLATILE)
my_effect.ToggleActivate()
else if(Touching.id in toxic)
if(my_effect.trigger == TRIGGER_TOXIN)
my_effect.ToggleActivate()
/datum/component/artifact_master/proc/on_moved()
for(var/datum/artifact_effect/my_effect in my_effects)
if(my_effect)
my_effect.UpdateMove()
/datum/component/artifact_master/process()
if(!holder) // Some instances can be created and rapidly lose their holder, if they are destroyed rapidly on creation. IE, during excavation.
STOP_PROCESSING(SSobj, src)
if(!QDELETED(src))
qdel(src)
return
var/turf/L = holder.loc
if(!istype(L) && !isliving(L)) // We're inside a non-mob container or on null turf, either way stop processing effects
return
if(istype(holder, /atom/movable))
var/atom/movable/HA = holder
if(HA.pulledby)
on_bumped(holder, HA.pulledby)
for(var/datum/artifact_effect/my_effect in my_effects)
if(my_effect)
my_effect.UpdateMove()
//if any of our effects rely on environmental factors, work that out
var/trigger_cold = 0
var/trigger_hot = 0
var/trigger_phoron = 0
var/trigger_oxy = 0
var/trigger_co2 = 0
var/trigger_nitro = 0
var/turf/T = get_turf(holder)
var/datum/gas_mixture/env = T.return_air()
if(env)
if(env.temperature < 225)
trigger_cold = 1
else if(env.temperature > 375)
trigger_hot = 1
if(env.gas["phoron"] >= 10)
trigger_phoron = 1
if(env.gas["oxygen"] >= 10)
trigger_oxy = 1
if(env.gas["carbon_dioxide"] >= 10)
trigger_co2 = 1
if(env.gas["nitrogen"] >= 10)
trigger_nitro = 1
for(var/datum/artifact_effect/my_effect in my_effects)
my_effect.artifact_id = artifact_id
my_effect.process()
//COLD ACTIVATION
if(my_effect.trigger == TRIGGER_COLD && (trigger_cold ^ my_effect.activated))
my_effect.ToggleActivate()
//HEAT ACTIVATION
if(my_effect.trigger == TRIGGER_HEAT && (trigger_hot ^ my_effect.activated))
my_effect.ToggleActivate()
//PHORON GAS ACTIVATION
if(my_effect.trigger == TRIGGER_PHORON && (trigger_phoron ^ my_effect.activated))
my_effect.ToggleActivate()
//OXYGEN GAS ACTIVATION
if(my_effect.trigger == TRIGGER_OXY && (trigger_oxy ^ my_effect.activated))
my_effect.ToggleActivate()
//CO2 GAS ACTIVATION
if(my_effect.trigger == TRIGGER_CO2 && (trigger_co2 ^ my_effect.activated))
my_effect.ToggleActivate()
//NITROGEN GAS ACTIVATION
if(my_effect.trigger == TRIGGER_NITRO && (trigger_nitro ^ my_effect.activated))
my_effect.ToggleActivate()

View File

@@ -4,6 +4,9 @@
effect_type = EFFECT_PSIONIC
var/mob/living/target = null
effect_state = "pulsing"
effect_color = "#00c3ff"
/datum/artifact_effect/animate_anomaly/ToggleActivate(var/reveal_toggle = 1)
..()
find_target()
@@ -13,21 +16,24 @@
effectrange = max(3, effectrange)
/datum/artifact_effect/animate_anomaly/proc/find_target()
if(!target || target.z != holder.z || get_dist(target, holder) > effectrange)
var/atom/masterholder = get_master_holder()
if(!target || target.z != masterholder.z || get_dist(target, masterholder) > effectrange)
var/mob/living/ClosestMob = null
for(var/mob/living/L in range(effectrange, holder))
for(var/mob/living/L in range(effectrange, get_turf(masterholder)))
if(!L.mind)
continue
if(!ClosestMob)
ClosestMob = L
continue
if(!L.stat)
if(get_dist(holder, L) < get_dist(holder, ClosestMob))
if(get_dist(masterholder, L) < get_dist(masterholder, ClosestMob))
ClosestMob = L
target = ClosestMob
/datum/artifact_effect/animate_anomaly/DoEffectTouch(var/mob/living/user)
var/atom/holder = get_master_holder()
var/obj/O = holder
var/turf/T = get_step_away(O, user)
@@ -36,25 +42,23 @@
O.visible_message("<span class='alien'>\The [holder] lurches away from [user]</span>")
/datum/artifact_effect/animate_anomaly/DoEffectAura()
var/obj/O = holder
if(!target || target.z != O.z || get_dist(target, O) > effectrange)
target = null
var/obj/O = get_master_holder()
find_target()
var/turf/T = get_step_to(O, target)
if(target && istype(T) && istype(O.loc, /turf))
if(get_dist(O, T) > 1)
O.Move(T)
O.visible_message("<span class='alien'>\The [holder] lurches toward [target]</span>")
if(!target || !istype(O))
return
O.dir = get_dir(O, target)
if(!target || !istype(O))
return
O.dir = get_dir(O, target)
if(istype(O.loc, /turf))
if(get_dist(O.loc, target.loc) > 1)
O.Move(get_step_to(O, target))
O.visible_message("<span class='alien'>\The [O] lurches toward [target]</span>")
/datum/artifact_effect/animate_anomaly/DoEffectPulse()
var/obj/O = holder
if(!target || target.z != O.z || get_dist(target, O) > effectrange)
target = null
find_target()
var/turf/T = get_step_to(O, target)
if(target && istype(T) && istype(O.loc, /turf))
if(get_dist(O, T) > 1)
O.Move(T)
O.visible_message("<span class='alien'>\The [holder] lurches toward [target]</span>")
DoEffectAura()

View File

@@ -25,6 +25,9 @@
"OH GOD!",
"HELP ME!")
effect_state = "summoning"
effect_color = "#643232"
/datum/artifact_effect/badfeeling/DoEffectTouch(var/mob/user)
if(user)
if (istype(user, /mob/living/carbon/human))
@@ -39,6 +42,7 @@
H.dizziness += rand(3,5)
/datum/artifact_effect/badfeeling/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))
@@ -53,6 +57,7 @@
return 1
/datum/artifact_effect/badfeeling/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))

View File

@@ -2,6 +2,9 @@
name = "berserk"
effect_type = EFFECT_PSIONIC
effect_state = "summoning"
effect_color = "#5f0000"
/datum/artifact_effect/berserk/proc/apply_berserk(var/mob/living/L)
if(!istype(L))
return FALSE
@@ -28,6 +31,7 @@
return TRUE
/datum/artifact_effect/berserk/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for(var/mob/living/L in range(src.effectrange,T))
@@ -36,6 +40,7 @@
return TRUE
/datum/artifact_effect/berserk/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for(var/mob/living/L in range(src.effectrange,T))

View File

@@ -25,6 +25,9 @@
"Butcher them!",
"Feast!")
effect_state = "summoning"
effect_color = "#c50303"
/datum/artifact_effect/cannibalfeeling/DoEffectTouch(var/mob/user)
if(user)
if (istype(user, /mob/living/carbon/human))
@@ -41,6 +44,7 @@
H.nutrition = H.nutrition / 1.5
/datum/artifact_effect/cannibalfeeling/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))
@@ -57,6 +61,7 @@
return 1
/datum/artifact_effect/cannibalfeeling/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))

View File

@@ -4,6 +4,8 @@
effect_type = EFFECT_ELECTRO
var/last_message
effect_color = "#ffee06"
/datum/artifact_effect/cellcharge/DoEffectTouch(var/mob/user)
if(user)
if(isrobot(user))
@@ -14,6 +16,7 @@
return 1
/datum/artifact_effect/cellcharge/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/obj/machinery/power/apc/C in GLOB.apcs)
@@ -42,6 +45,7 @@
return 1
/datum/artifact_effect/cellcharge/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/obj/machinery/power/apc/C in GLOB.apcs)

View File

@@ -4,6 +4,9 @@
effect_type = EFFECT_ELECTRO
var/last_message
effect_state = "pulsing"
effect_color = "#fbff02"
/datum/artifact_effect/celldrain/DoEffectTouch(var/mob/user)
if(user)
if(istype(user, /mob/living/silicon/robot))
@@ -16,6 +19,7 @@
return 1
/datum/artifact_effect/celldrain/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/obj/machinery/power/apc/C in GLOB.apcs)
@@ -44,6 +48,7 @@
return 1
/datum/artifact_effect/celldrain/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/obj/machinery/power/apc/C in GLOB.apcs)

View File

@@ -3,6 +3,8 @@
name = "cold"
var/target_temp
effect_color = "#b3f6ff"
/datum/artifact_effect/cold/New()
..()
target_temp = rand(0, 250)
@@ -10,6 +12,7 @@
effect_type = pick(EFFECT_ORGANIC, EFFECT_BLUESPACE, EFFECT_SYNTH)
/datum/artifact_effect/cold/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
if(holder)
to_chat(user, "<font color='blue'>A chill passes up your spine!</font>")
var/datum/gas_mixture/env = holder.loc.return_air()
@@ -17,6 +20,7 @@
env.temperature = max(env.temperature - rand(5,50), 0)
/datum/artifact_effect/cold/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env && env.temperature > target_temp)

View File

@@ -4,6 +4,9 @@
effect_type = EFFECT_ORGANIC
var/severity
effect_state = "smoke"
effect_color = "#77ff83"
/datum/artifact_effect/dnaswitch/New()
..()
if(effect == EFFECT_AURA)
@@ -28,6 +31,7 @@
return 1
/datum/artifact_effect/dnaswitch/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for(var/mob/living/carbon/human/H in range(src.effectrange,T))
@@ -47,6 +51,7 @@
scramble(0, H, weakness * severity)
/datum/artifact_effect/dnaswitch/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for(var/mob/living/carbon/human/H in range(200, T))

View File

@@ -3,7 +3,10 @@
name = "electric field"
effect_type = EFFECT_ENERGY
effect_color = "#ffff00"
/datum/artifact_effect/electric_field/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
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.
@@ -27,6 +30,7 @@
L.electrocute_act(rand(25, 40), holder, 0.75, BP_TORSO)
/datum/artifact_effect/electric_field/DoEffectAura()
var/atom/holder = get_master_holder()
var/list/nearby_mobs = list()
for(var/mob/living/L in oview(effectrange, get_turf(holder)))
if(!L.stat)
@@ -48,6 +52,7 @@
L.electrocute_act(rand(1, 10), holder, 0.75, BP_TORSO)
/datum/artifact_effect/electric_field/DoEffectPulse()
var/atom/holder = get_master_holder()
var/list/nearby_mobs = list()
for(var/mob/living/L in oview(effectrange, get_turf(holder)))
if(!L.stat)

View File

@@ -2,11 +2,14 @@
name = "emp"
effect_type = EFFECT_ELECTRO
effect_state = "empdisable"
/datum/artifact_effect/emp/New()
..()
effect = EFFECT_PULSE
/datum/artifact_effect/emp/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
empulse(T, effectrange/4, effectrange/3, effectrange/2, effectrange)

View File

@@ -2,6 +2,9 @@
name = "feysight"
effect_type = EFFECT_PSIONIC
effect_state = "pulsing"
effect_color = "#00c763"
/datum/artifact_effect/feysight/proc/apply_modifier(var/mob/living/L)
if(!istype(L))
return FALSE
@@ -28,6 +31,7 @@
return TRUE
/datum/artifact_effect/feysight/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for(var/mob/living/L in range(src.effectrange,T))
@@ -36,6 +40,7 @@
return TRUE
/datum/artifact_effect/feysight/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for(var/mob/living/L in range(src.effectrange,T))

View File

@@ -3,11 +3,15 @@
var/list/created_field = list()
effect_type = EFFECT_PARTICLE
effect_state = "shield-old"
effect_color = "#00b7ff"
/datum/artifact_effect/forcefield/New()
..()
trigger = TRIGGER_TOUCH
/datum/artifact_effect/forcefield/ToggleActivate()
var/atom/holder = get_master_holder()
..()
if(created_field.len)
for(var/obj/effect/energy_field/F in created_field)
@@ -35,6 +39,7 @@
E.adjust_strength(0.25, 0)
/datum/artifact_effect/forcefield/UpdateMove()
var/atom/holder = get_master_holder()
if(created_field.len && holder)
var/turf/T = get_turf(holder)
while(created_field.len < 16)

View File

@@ -5,6 +5,8 @@
var/list/my_glitterflies = list()
effect_color = "#8cd448"
/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
@@ -30,6 +32,7 @@
P.update_icon()
/datum/artifact_effect/gaia/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
to_chat(user, "<span class='alien'>You feel the presence of something long forgotten.</span>")
for(var/obj/machinery/portable_atmospherics/hydroponics/Tray in view(world.view,get_turf(holder)))
age_plantlife(Tray)
@@ -44,6 +47,7 @@
age_plantlife(P)
/datum/artifact_effect/gaia/DoEffectAura()
var/atom/holder = get_master_holder()
for(var/obj/machinery/portable_atmospherics/hydroponics/Tray in view(effectrange,holder))
age_plantlife(Tray)
if(prob(2))
@@ -57,6 +61,7 @@
age_plantlife(P)
/datum/artifact_effect/gaia/DoEffectPulse()
var/atom/holder = get_master_holder()
for(var/obj/machinery/portable_atmospherics/hydroponics/Tray in view(effectrange,holder))
age_plantlife(Tray)
if(prob(10))
@@ -70,6 +75,7 @@
age_plantlife(P)
/datum/artifact_effect/gaia/process()
var/atom/holder = get_master_holder()
..()
listclearnulls(my_glitterflies)

View File

@@ -1,18 +1,22 @@
/datum/artifact_effect/gasco2
name = "CO2 creation"
effect_color = "#a5a5a5"
/datum/artifact_effect/gasco2/New()
..()
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
effect_type = pick(EFFECT_BLUESPACE, EFFECT_SYNTH)
/datum/artifact_effect/gasco2/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))
holder_loc.assume_gas("carbon_dioxide", rand(2, 15))
/datum/artifact_effect/gasco2/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))

View File

@@ -1,18 +1,22 @@
/datum/artifact_effect/gasnitro
name = "N2 creation"
effect_color = "#c2d3d8"
/datum/artifact_effect/gasnitro/New()
..()
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
effect_type = pick(EFFECT_BLUESPACE, EFFECT_SYNTH)
/datum/artifact_effect/gasnitro/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))
holder_loc.assume_gas("nitrogen", rand(2, 15))
/datum/artifact_effect/gasnitro/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))

View File

@@ -7,12 +7,14 @@
effect_type = pick(EFFECT_BLUESPACE, EFFECT_SYNTH)
/datum/artifact_effect/gasoxy/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))
holder_loc.assume_gas("oxygen", rand(2, 15))
/datum/artifact_effect/gasoxy/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))

View File

@@ -1,18 +1,22 @@
/datum/artifact_effect/gasphoron
name = "phoron creation"
effect_color = "#c408ba"
/datum/artifact_effect/gasphoron/New()
..()
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
effect_type = pick(EFFECT_BLUESPACE, EFFECT_SYNTH)
/datum/artifact_effect/gasphoron/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))
holder_loc.assume_gas("phoron", rand(2, 15))
/datum/artifact_effect/gasphoron/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))

View File

@@ -7,12 +7,14 @@
effect_type = pick(EFFECT_BLUESPACE, EFFECT_SYNTH)
/datum/artifact_effect/gassleeping/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))
holder_loc.assume_gas("nitrous_oxide", rand(2, 15))
/datum/artifact_effect/gassleeping/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/holder_loc = holder.loc
if(istype(holder_loc))

View File

@@ -23,6 +23,9 @@
"You're so happy suddenly, you almost want to dance and sing.",
"You feel like the world is out to help you.")
effect_state = "summoning"
effect_color = "#009118"
/datum/artifact_effect/goodfeeling/DoEffectTouch(var/mob/user)
if(user)
if (istype(user, /mob/living/carbon/human))
@@ -37,6 +40,7 @@
H.dizziness += rand(3,5)
/datum/artifact_effect/goodfeeling/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))
@@ -51,6 +55,7 @@
return 1
/datum/artifact_effect/goodfeeling/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))

View File

@@ -5,10 +5,14 @@
var/last_wave_pull = 0
effect_state = "gravisphere"
effect_color = "#d8c3ff"
/datum/artifact_effect/gravity_wave/DoEffectTouch(var/mob/user)
gravwave(user, effectrange, STAGE_TWO)
/datum/artifact_effect/gravity_wave/DoEffectAura()
var/atom/holder = get_master_holder()
var/seconds_since_last_pull = max(0, round((last_wave_pull - world.time) / 10))
if(prob(10 + seconds_since_last_pull))
@@ -17,6 +21,7 @@
gravwave(get_turf(holder), effectrange, STAGE_TWO)
/datum/artifact_effect/gravity_wave/DoEffectPulse()
var/atom/holder = get_master_holder()
holder.visible_message("<span class='alien'>\The [holder] distorts as local gravity intensifies, and shifts toward it.</span>")
gravwave(get_turf(holder), effectrange, STAGE_TWO)

View File

@@ -1,6 +1,7 @@
/datum/artifact_effect/heal
name = "heal"
effect_type = EFFECT_ORGANIC
effect_color = "#4649ff"
/datum/artifact_effect/heal/DoEffectTouch(var/mob/toucher)
//todo: check over this properly
@@ -33,6 +34,7 @@
return 1
/datum/artifact_effect/heal/DoEffectAura()
var/atom/holder = get_master_holder()
//todo: check over this properly
if(holder)
var/turf/T = get_turf(holder)
@@ -49,6 +51,7 @@
C.updatehealth()
/datum/artifact_effect/heal/DoEffectPulse()
var/atom/holder = get_master_holder()
//todo: check over this properly
if(holder)
var/turf/T = get_turf(holder)

View File

@@ -2,6 +2,7 @@
/datum/artifact_effect/heat
name = "heat"
var/target_temp
effect_color = "#ff6600"
/datum/artifact_effect/heat/New()
..()
@@ -10,6 +11,7 @@
target_temp = rand(300, 600)
/datum/artifact_effect/heat/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
if(holder)
to_chat(user, "<font color='red'> You feel a wave of heat travel up your spine!</font>")
var/datum/gas_mixture/env = holder.loc.return_air()
@@ -17,6 +19,7 @@
env.temperature += rand(5,50)
/datum/artifact_effect/heat/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env && env.temperature < target_temp)

View File

@@ -2,6 +2,8 @@
name = "hurt"
effect_type = EFFECT_ORGANIC
effect_color = "#6d1212"
/datum/artifact_effect/hurt/DoEffectTouch(var/mob/toucher)
if(toucher)
var/weakness = GetAnomalySusceptibility(toucher)
@@ -20,6 +22,7 @@
C.weakened += 6 * weakness
/datum/artifact_effect/hurt/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(src.effectrange,T))
@@ -35,6 +38,7 @@
C.updatehealth()
/datum/artifact_effect/hurt/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(effectrange, T))

View File

@@ -3,6 +3,9 @@
name = "poltergeist"
effect_type = EFFECT_ENERGY
effect_state = "shield2"
effect_color = "#a824c9"
/datum/artifact_effect/poltergeist/proc/throw_at_mob(var/mob/living/target, var/damage = 20)
var/list/valid_targets = list()
@@ -19,6 +22,7 @@
throw_at_mob(user, rand(10, 30))
/datum/artifact_effect/poltergeist/DoEffectAura()
var/atom/holder = get_master_holder()
var/mob/living/target = null
for(var/mob/living/L in oview(get_turf(holder), effectrange))
if(L.stat || !L.mind)
@@ -33,6 +37,7 @@
throw_at_mob(target, rand(15, 30))
/datum/artifact_effect/poltergeist/DoEffectPulse()
var/atom/holder = get_master_holder()
var/mob/living/target = null
for(var/mob/living/L in oview(get_turf(holder), effectrange))
if(L.stat || !L.mind)

View File

@@ -2,6 +2,8 @@
name = "radiation"
var/radiation_amount
effect_color = "#007006"
/datum/artifact_effect/radiate/New()
..()
radiation_amount = rand(1, 10)
@@ -14,11 +16,13 @@
return 1
/datum/artifact_effect/radiate/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
SSradiation.flat_radiate(holder, radiation_amount, src.effectrange)
return 1
/datum/artifact_effect/radiate/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
SSradiation.radiate(holder, ((radiation_amount * 3) * (sqrt(src.effectrange)))) //Need to get feedback on this //VOREStation Edit - Was too crazy-strong.
return 1

View File

@@ -4,7 +4,11 @@
var/stored_life = 0
effect_state = "pulsing"
effect_color = "#ff0000"
/datum/artifact_effect/resurrect/proc/steal_life(var/mob/living/target = null)
var/atom/holder = get_master_holder()
if(!istype(target))
return 0
@@ -16,6 +20,7 @@
return 0
/datum/artifact_effect/resurrect/proc/give_life(var/mob/living/target = null)
var/atom/holder = get_master_holder()
if(!istype(target))
return
@@ -34,6 +39,7 @@
stored_life = 0
/datum/artifact_effect/resurrect/proc/attempt_revive(var/mob/living/L = null)
var/atom/holder = get_master_holder()
spawn()
if(istype(L, /mob/living/simple_mob))
var/mob/living/simple_mob/SM = L
@@ -70,6 +76,7 @@
holder.visible_message("<span class='alien'>\The [H]'s eyes open in a flash of light!</span>")
/datum/artifact_effect/resurrect/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
for(var/mob/living/L in oview(effectrange, get_turf(holder)))
stored_life += 4 * steal_life(L)
@@ -80,6 +87,7 @@
break
/datum/artifact_effect/resurrect/DoEffectAura()
var/atom/holder = get_master_holder()
for(var/mob/living/L in oview(effectrange, get_turf(holder)))
stored_life += steal_life(L)
@@ -90,6 +98,7 @@
break
/datum/artifact_effect/resurrect/DoEffectPulse()
var/atom/holder = get_master_holder()
for(var/mob/living/L in oview(effectrange, get_turf(holder)))
stored_life += 2 * steal_life(L)

View File

@@ -2,6 +2,8 @@
name = "robotic healing"
var/last_message
effect_color = "#3879ad"
/datum/artifact_effect/roboheal/New()
..()
effect_type = pick(EFFECT_ELECTRO, EFFECT_PARTICLE)
@@ -16,6 +18,7 @@
return 1
/datum/artifact_effect/roboheal/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
@@ -28,6 +31,7 @@
return 1
/datum/artifact_effect/roboheal/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,T))

View File

@@ -2,6 +2,8 @@
name = "robotic harm"
var/last_message
effect_color = "#5432cf"
/datum/artifact_effect/robohurt/New()
..()
effect_type = pick(EFFECT_ELECTRO, EFFECT_PARTICLE)
@@ -16,6 +18,7 @@
return 1
/datum/artifact_effect/robohurt/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
@@ -28,6 +31,7 @@
return 1
/datum/artifact_effect/robohurt/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,T))

View File

@@ -1,6 +1,7 @@
//todo
/datum/artifact_effect/sleepy
name = "sleepy"
effect_color = "#a36fa1"
/datum/artifact_effect/sleepy/New()
..()
@@ -20,6 +21,7 @@
return 1
/datum/artifact_effect/sleepy/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))
@@ -34,6 +36,7 @@
return 1
/datum/artifact_effect/sleepy/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for(var/mob/living/carbon/human/H in range(src.effectrange, T))

View File

@@ -1,5 +1,6 @@
/datum/artifact_effect/stun
name = "stun"
effect_color = "#00eeff"
/datum/artifact_effect/stun/New()
..()
@@ -16,6 +17,7 @@
C.Stun(rand(1,10) * susceptibility)
/datum/artifact_effect/stun/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(src.effectrange,T))
@@ -30,6 +32,7 @@
to_chat(C, "<font color='red'>You feel numb.</font>")
/datum/artifact_effect/stun/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(src.effectrange,T))

View File

@@ -1,8 +1,11 @@
/datum/artifact_effect/teleport
name = "teleport"
effect_type = EFFECT_BLUESPACE
effect_state = "pulsing"
effect_color = "#88ffdb"
/datum/artifact_effect/teleport/DoEffectTouch(var/mob/user)
var/atom/holder = get_master_holder()
var/weakness = GetAnomalySusceptibility(user)
if(prob(100 * weakness))
to_chat(user, "<font color='red'>You are suddenly zapped away elsewhere!</font>")
@@ -20,6 +23,7 @@
sparks.start()
/datum/artifact_effect/teleport/DoEffectAura()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/M in range(src.effectrange,T))
@@ -39,6 +43,7 @@
sparks.start()
/datum/artifact_effect/teleport/DoEffectPulse()
var/atom/holder = get_master_holder()
if(holder)
var/turf/T = get_turf(holder)
for (var/mob/living/M in range(src.effectrange, T))

View File

@@ -9,7 +9,11 @@
var/charges = 0
var/list/nearby_mobs = list()
effect_state = "gravisphere"
effect_color = "#ff0000"
/datum/artifact_effect/vampire/proc/bloodcall(var/mob/living/carbon/human/M)
var/atom/holder = get_master_holder()
last_bloodcall = world.time
if(istype(M))
playsound(holder, pick('sound/hallucinations/wail.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/far_noise.ogg'), 50, 1, -3)
@@ -23,30 +27,29 @@
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))
M.vessel.remove_reagent("blood",rand(10,30))
/datum/artifact_effect/vampire/DoEffectTouch(var/mob/user)
bloodcall(user)
DoEffectAura()
/datum/artifact_effect/vampire/DoEffectAura()
var/atom/holder = get_master_holder()
if(nearby_mobs.len)
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)
if(world.time - bloodcall_interval >= last_bloodcall && LAZYLEN(nearby_mobs))
var/mob/living/carbon/human/M = pick(nearby_mobs)
if(M in view(effectrange,holder) && M.health > 20)
if(prob(50))
if(get_dist(M, T) <= effectrange && M.health > 20)
bloodcall(M)
holder.Beam(M, icon_state = "drainbeam", time = 1 SECOND)
if(world.time - last_eat > eat_interval)
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
@@ -62,13 +65,13 @@
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(get_turf(pick(view(1,T))))
new manifestation(pick(RANGE_TURFS(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(get_turf(pick(view(1,T))))
new spawn_type(pick(RANGE_TURFS(1,T)))
playsound(holder, 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))

View File

@@ -15,18 +15,20 @@
var/additional_desc = ""
var/obj/item/weapon/new_item
var/source_material = ""
var/apply_material_decorations = 1
var/apply_image_decorations = 0
var/apply_material_decorations = TRUE
var/apply_image_decorations = FALSE
var/material_descriptor = ""
var/apply_prefix = 1
var/apply_prefix = TRUE
var/become_anomalous = FALSE
if(prob(40))
material_descriptor = pick("rusted ","dusty ","archaic ","fragile ", "damaged", "pristine")
source_material = pick("cordite","quadrinium","steel","titanium","aluminium","ferritic-alloy","plasteel","duranium")
var/talkative = 0
var/talkative = FALSE
if(prob(5))
talkative = 1
talkative = TRUE
//for all items here:
//icon_state
@@ -41,7 +43,7 @@
new_item = new /obj/item/weapon/reagent_containers/glass/beaker(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = "bowl"
apply_image_decorations = 1
apply_image_decorations = TRUE
if(prob(40))
new_item.color = rgb(rand(0,255),rand(0,255),rand(0,255))
if(prob(20))
@@ -55,7 +57,7 @@
new_item = new /obj/item/weapon/reagent_containers/glass/beaker(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = "urn[rand(1,2)]"
apply_image_decorations = 1
apply_image_decorations = TRUE
if(prob(20))
additional_desc = "It [pick("whispers faintly","makes a quiet roaring sound","whistles softly","thrums quietly","throbs")] if you put it to your ear."
if(ARCHAEO_CUTLERY)
@@ -88,7 +90,9 @@
item_type = "instrument"
icon_state = "instrument"
if(prob(30))
apply_image_decorations = 1
become_anomalous = TRUE
if(prob(30))
apply_image_decorations = TRUE
additional_desc = "[pick("You're not sure how anyone could have played this",\
"You wonder how many mouths the creator had",\
"You wonder what it sounds like",\
@@ -109,16 +113,16 @@
chance += 10
item_type = new_item.name
apply_prefix = 0
apply_material_decorations = 0
apply_image_decorations = 1
apply_prefix = FALSE
apply_material_decorations = FALSE
apply_image_decorations = TRUE
if(ARCHAEO_HANDCUFFS)
item_type = "handcuffs"
new_item = new /obj/item/weapon/handcuffs(src.loc)
additional_desc = "[pick("They appear to be for securing two things together","Looks kinky","Doesn't seem like a children's toy")]."
if(ARCHAEO_BEARTRAP)
item_type = "[pick("wicked","evil","byzantine","dangerous")] looking [pick("device","contraption","thing","trap")]"
apply_prefix = 0
apply_prefix = FALSE
new_item = new /obj/item/weapon/beartrap(src.loc)
if(prob(40))
new_item.color = rgb(rand(0,255),rand(0,255),rand(0,255))
@@ -130,7 +134,7 @@
new_item = new /obj/item/weapon/flame/lighter(src.loc)
additional_desc = "There is a tiny device attached."
if(prob(30))
apply_image_decorations = 1
apply_image_decorations = TRUE
if(ARCHAEO_BOX)
item_type = "box"
new_item = new /obj/item/weapon/storage/box(src.loc)
@@ -142,7 +146,7 @@
new_box.max_storage_space = rand(storage_amount, storage_amount * 10)
if(prob(30))
LAZYSET(new_item.origin_tech, TECH_ARCANE, 1)
apply_image_decorations = 1
apply_image_decorations = TRUE
if(ARCHAEO_GASTANK)
item_type = "[pick("cylinder","tank","chamber")]"
if(prob(25))
@@ -163,12 +167,12 @@
new_item = new /obj/item/weapon/tool/screwdriver(src.loc)
if(prob(40))
new_item.color = rgb(rand(0,255),rand(0,255),rand(0,255))
apply_image_decorations = 1
apply_image_decorations = TRUE
additional_desc = "[pick("It doesn't look safe.",\
"You wonder what it was used for",\
"There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains on it")]."
if(ARCHAEO_METAL)
apply_material_decorations = 0
apply_material_decorations = FALSE
var/list/possible_spawns = list()
possible_spawns += /obj/item/stack/material/steel
possible_spawns += /obj/item/stack/material/plasteel
@@ -193,9 +197,11 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "pen1"
LAZYSET(new_item.origin_tech, TECH_ARCANE, 1)
apply_image_decorations = 1
apply_image_decorations = TRUE
if(ARCHAEO_CRYSTAL)
apply_prefix = 0
if(prob(40))
become_anomalous = TRUE
apply_prefix = FALSE
if(prob(25))
icon = 'icons/obj/xenoarchaeology.dmi'
item_type = "smooth green crystal"
@@ -210,9 +216,9 @@
icon_state = "changerock"
additional_desc = pick("It shines faintly as it catches the light.","It appears to have a faint inner glow.","It seems to draw you inward as you look it at.","Something twinkles faintly as you look at it.","It's mesmerizing to behold.")
apply_material_decorations = 0
apply_material_decorations = FALSE
if(prob(10))
apply_image_decorations = 1
apply_image_decorations = TRUE
if(prob(25))
new_item = new /obj/item/device/soulstone(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
@@ -220,18 +226,18 @@
LAZYSET(new_item.origin_tech, TECH_ARCANE, 2)
if(ARCHAEO_CULTBLADE)
//cultblade
apply_prefix = 0
apply_prefix = FALSE
new_item = new /obj/item/weapon/melee/cultblade(src.loc)
apply_material_decorations = 0
apply_image_decorations = 0
apply_material_decorations = FALSE
apply_image_decorations = FALSE
if(ARCHAEO_TELEBEACON)
new_item = new /obj/item/device/radio/beacon(src.loc)
talkative = 0
talkative = FALSE
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = "unknown[rand(1,4)]"
new_item.desc = ""
if(ARCHAEO_CLAYMORE)
apply_prefix = 0
apply_prefix = FALSE
new_item = new /obj/item/weapon/material/sword(src.loc)
new_item.force = 10
new_item.name = pick("great-sword","claymore","longsword","broadsword","shortsword","gladius")
@@ -241,7 +247,7 @@
new_item.icon_state = "blade1"
if(ARCHAEO_CULTROBES)
//arcane clothing
apply_prefix = 0
apply_prefix = FALSE
var/list/possible_spawns = list(/obj/item/clothing/head/culthood,
/obj/item/clothing/head/culthood/magus,
/obj/item/clothing/head/culthood/alt,
@@ -252,25 +258,28 @@
LAZYSET(new_item.origin_tech, TECH_ARCANE, 1)
if(ARCHAEO_SOULSTONE)
//soulstone
apply_prefix = 0
become_anomalous = TRUE
apply_prefix = FALSE
new_item = new /obj/item/device/soulstone(src.loc)
item_type = new_item.name
apply_material_decorations = 0
apply_material_decorations = FALSE
LAZYSET(new_item.origin_tech, TECH_ARCANE, 2)
if(ARCHAEO_SHARD)
if(prob(50))
new_item = new /obj/item/weapon/material/shard(src.loc)
else
new_item = new /obj/item/weapon/material/shard/phoron(src.loc)
apply_prefix = 0
apply_image_decorations = 0
apply_material_decorations = 0
apply_prefix = FALSE
apply_image_decorations = FALSE
apply_material_decorations = FALSE
if(ARCHAEO_RODS)
apply_prefix = 0
apply_prefix = FALSE
new_item = new /obj/item/stack/rods(src.loc)
apply_image_decorations = 0
apply_material_decorations = 0
apply_image_decorations = FALSE
apply_material_decorations = FALSE
if(ARCHAEO_STOCKPARTS)
if(prob(30))
become_anomalous = TRUE
var/list/possible_spawns = typesof(/obj/item/weapon/stock_parts)
possible_spawns -= /obj/item/weapon/stock_parts
possible_spawns -= /obj/item/weapon/stock_parts/subspace
@@ -278,9 +287,9 @@
var/new_type = pick(possible_spawns)
new_item = new new_type(src.loc)
item_type = new_item.name
apply_material_decorations = 0
apply_material_decorations = FALSE
if(ARCHAEO_KATANA)
apply_prefix = 0
apply_prefix = FALSE
new_item = new /obj/item/weapon/material/sword/katana(src.loc)
new_item.force = 10
new_item.name = "katana"
@@ -349,9 +358,11 @@
item_type = "gun"
if(ARCHAEO_UNKNOWN)
if(prob(20))
become_anomalous = TRUE
//completely unknown alien device
if(prob(50))
apply_image_decorations = 0
apply_image_decorations = FALSE
if(ARCHAEO_FOSSIL)
//fossil bone/skull
//new_item = new /obj/item/weapon/fossil/base(src.loc)
@@ -362,30 +373,30 @@
var/spawn_type = pickweight(candidates)
new_item = new spawn_type(src.loc)
apply_prefix = 0
apply_prefix = FALSE
additional_desc = "A fossilised part of an alien, long dead."
apply_image_decorations = 0
apply_material_decorations = 0
apply_image_decorations = FALSE
apply_material_decorations = FALSE
if(ARCHAEO_SHELL)
//fossil shell
new_item = new /obj/item/weapon/fossil/shell(src.loc)
apply_prefix = 0
apply_prefix = FALSE
additional_desc = "A fossilised, pre-Stygian alien crustacean."
apply_image_decorations = 0
apply_material_decorations = 0
apply_image_decorations = FALSE
apply_material_decorations = FALSE
if(prob(10))
apply_image_decorations = 1
apply_image_decorations = TRUE
if(ARCHAEO_PLANT)
//fossil plant
new_item = new /obj/item/weapon/fossil/plant(src.loc)
item_type = new_item.name
additional_desc = "A fossilised shred of alien plant matter."
apply_image_decorations = 0
apply_material_decorations = 0
apply_prefix = 0
apply_image_decorations = FALSE
apply_material_decorations = FALSE
apply_prefix = FALSE
if(ARCHAEO_REMAINS_HUMANOID)
//humanoid remains
apply_prefix = 0
apply_prefix = FALSE
item_type = "humanoid [pick("remains","skeleton")]"
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
@@ -396,11 +407,11 @@
"The bones are scored by numerous burns and partially melted.",\
"The are battered and broken, in some cases less than splinters are left.",\
"The mouth is wide open in a death rictus, the victim would appear to have died screaming.")
apply_image_decorations = 0
apply_material_decorations = 0
apply_image_decorations = FALSE
apply_material_decorations = FALSE
if(ARCHAEO_REMAINS_ROBOT)
//robot remains
apply_prefix = 0
apply_prefix = FALSE
item_type = "[pick("mechanical","robotic","cyborg")] [pick("remains","chassis","debris")]"
icon = 'icons/mob/robots.dmi'
icon_state = "remainsrobot"
@@ -411,11 +422,11 @@
"The chassis is scored by numerous burns and partially melted.",\
"The chassis is battered and broken, in some cases only chunks of metal are left.",\
"A pile of wires and crap metal that looks vaguely robotic.")
apply_image_decorations = 0
apply_material_decorations = 0
apply_image_decorations = FALSE
apply_material_decorations = FALSE
if(ARCHAEO_REMAINS_XENO)
//xenos remains
apply_prefix = 0
apply_prefix = FALSE
item_type = "alien [pick("remains","skeleton")]"
icon = 'icons/effects/blood.dmi'
icon_state = "remainsxeno"
@@ -427,8 +438,8 @@
"The are battered and broken, in some cases less than splinters are left.",\
"This creature would have been twisted and monstrous when it was alive.",\
"It doesn't look human.")
apply_image_decorations = 0
apply_material_decorations = 0
apply_image_decorations = FALSE
apply_material_decorations = FALSE
if(ARCHAEO_GASMASK)
//gas mask
if(prob(25))
@@ -680,6 +691,9 @@
new_item.origin_tech[TECH_ARCANE] += 1
new_item.origin_tech[TECH_PRECURSOR] += 1
if(become_anomalous)
new_item.become_anomalous()
var/turf/simulated/mineral/T = get_turf(new_item)
if(istype(T))
T.last_find = new_item
@@ -691,3 +705,6 @@
LAZYINITLIST(origin_tech)
origin_tech[TECH_ARCANE] += 1
origin_tech[TECH_PRECURSOR] += 1
if(become_anomalous)
become_anomalous()

View File

@@ -138,13 +138,37 @@
var/obj/machinery/artifact/A = scanned_obj
var/out = "Anomalous alien device - composed of an unknown alloy.<br><br>"
if(A.my_effect)
out += A.my_effect.getDescription()
var/datum/component/artifact_master/AMast = A.artifact_master
var/datum/artifact_effect/AEff = AMast.get_primary()
if(A.secondary_effect && A.secondary_effect.activated)
out += AEff.getDescription()
if(AMast.my_effects.len > 1)
out += "<br><br>Internal scans indicate ongoing secondary activity operating independently from primary systems.<br><br>"
out += A.secondary_effect.getDescription()
for(var/datum/artifact_effect/my_effect in A.artifact_master.my_effects - AEff)
if(my_effect)
out += my_effect.getDescription()
return out
else
var/datum/component/artifact_master/ScannedMaster = scanned_obj.GetComponent(/datum/component/artifact_master)
if(istype(ScannedMaster))
var/out = "Anomalous reality warp - Object has been altered to disobey known laws of physics.<br><br>"
var/datum/artifact_effect/AEff = ScannedMaster.get_primary()
out += AEff.getDescription()
if(ScannedMaster.my_effects.len > 1)
out += "<br><br>Resonant scans indicate asynchronous reality modulation:<br><br>"
for(var/datum/artifact_effect/my_effect in ScannedMaster.my_effects - AEff)
if(my_effect)
out += my_effect.getDescription()
return out
return "[scanned_obj.name] - mundane application."

View File

@@ -148,10 +148,12 @@
cur_artifact = analysed
//if both effects are active, we can't harvest either
if(cur_artifact.my_effect && cur_artifact.my_effect.activated && cur_artifact.secondary_effect && cur_artifact.secondary_effect.activated)
var/list/active_effects = cur_artifact.artifact_master.get_active_effects()
if(active_effects.len > 1)
atom_say("Cannot harvest. Source is emitting conflicting energy signatures.")
return
if(!cur_artifact.my_effect.activated && !(cur_artifact.secondary_effect && cur_artifact.secondary_effect.activated))
else if(!active_effects.len)
atom_say("Cannot harvest. No energy emitting from source.")
return
@@ -163,34 +165,24 @@
//
var/datum/artifact_effect/source_effect
var/datum/artifact_effect/active_effect = active_effects[1]
//if we already have charge in the battery, we can only recharge it from the source artifact
if(inserted_battery.stored_charge > 0)
var/battery_matches_primary_id = 0
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.my_effect.artifact_id)
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.artifact_master.artifact_id)
battery_matches_primary_id = 1
if(battery_matches_primary_id && cur_artifact.my_effect.activated)
if(battery_matches_primary_id && active_effect.activated)
//we're good to recharge the primary effect!
source_effect = cur_artifact.my_effect
var/battery_matches_secondary_id = 0
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.secondary_effect.artifact_id)
battery_matches_secondary_id = 1
if(battery_matches_secondary_id && cur_artifact.secondary_effect.activated)
//we're good to recharge the secondary effect!
source_effect = cur_artifact.secondary_effect
source_effect = active_effect
if(!source_effect)
atom_say("Cannot harvest. Battery is charged with a different energy signature.")
else
//we're good to charge either
if(cur_artifact.my_effect.activated)
if(active_effect.activated)
//charge the primary effect
source_effect = cur_artifact.my_effect
else if(cur_artifact.secondary_effect.activated)
//charge the secondary effect
source_effect = cur_artifact.secondary_effect
source_effect = active_effect
if(source_effect)
@@ -258,3 +250,134 @@
inserted_battery.battery_effect.ToggleActivate()
src.visible_message("<b>[name]</b> states, \"Battery dump completed.\"")
icon_state = "incubator"
/obj/machinery/artifact_harvester/Topic(href, href_list)
if (href_list["harvest"])
if(!inserted_battery)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. No battery inserted.\"")
else if(inserted_battery.stored_charge >= inserted_battery.capacity)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. battery is full.\"")
else
//locate artifact on analysis pad
cur_artifact = null
var/articount = 0
var/obj/machinery/artifact/analysed
for(var/obj/machinery/artifact/A in get_turf(owned_scanner))
analysed = A
articount++
if(articount <= 0)
var/message = "<b>[src]</b> states, \"Cannot harvest. No noteworthy energy signature isolated.\""
src.visible_message(message)
else if(analysed && analysed.being_used)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Source already being harvested.\"")
else
if(articount > 1)
state("Cannot harvest. Too many artifacts on the pad.")
else if(analysed)
cur_artifact = analysed
//if both effects are active, we can't harvest either
var/list/active_effects = cur_artifact.artifact_master.get_active_effects()
if(active_effects.len > 1)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Source is emitting conflicting energy signatures.\"")
else if(!active_effects.len)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. No energy emitting from source.\"")
else
//see if we can clear out an old effect
//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
var/datum/artifact_effect/active_effect = active_effects[1]
//if we already have charge in the battery, we can only recharge it from the source artifact
if(inserted_battery.stored_charge > 0)
var/battery_matches_primary_id = 0
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.artifact_master.artifact_id)
battery_matches_primary_id = 1
if(battery_matches_primary_id && active_effect.activated)
//we're good to recharge the primary effect!
source_effect = active_effect
if(!source_effect)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Battery is charged with a different energy signature.\"")
else
//we're good to charge either
if(active_effect.activated)
//charge the primary effect
source_effect = active_effect
if(source_effect)
harvesting = 1
update_use_power(USE_POWER_ACTIVE)
cur_artifact.anchored = 1
cur_artifact.being_used = 1
icon_state = "incubator_on"
var/message = "<b>[src]</b> states, \"Beginning energy harvesting.\""
src.visible_message(message)
last_process = world.time
//duplicate the artifact's effect datum
if(!inserted_battery.battery_effect)
var/effecttype = source_effect.type
var/datum/artifact_effect/E = new effecttype(inserted_battery)
//duplicate it's unique settings
for(var/varname in list("chargelevelmax","artifact_id","effect","effectrange","trigger"))
E.vars[varname] = source_effect.vars[varname]
//copy the new datum into the battery
inserted_battery.battery_effect = E
inserted_battery.stored_charge = 0
if (href_list["stopharvest"])
if(harvesting)
if(harvesting < 0 && inserted_battery.battery_effect && inserted_battery.battery_effect.activated)
inserted_battery.battery_effect.ToggleActivate()
harvesting = 0
cur_artifact.anchored = 0
cur_artifact.being_used = 0
cur_artifact = null
src.visible_message("<b>[name]</b> states, \"Energy harvesting interrupted.\"")
icon_state = "incubator"
if (href_list["ejectbattery"])
src.inserted_battery.loc = src.loc
src.inserted_battery = null
if (href_list["drainbattery"])
if(inserted_battery)
if(inserted_battery.battery_effect && inserted_battery.stored_charge > 0)
if(alert("This action will dump all charge, safety gear is recommended before proceeding","Warning","Continue","Cancel"))
if(!inserted_battery.battery_effect.activated)
inserted_battery.battery_effect.ToggleActivate(1)
last_process = world.time
harvesting = -1
update_use_power(USE_POWER_ACTIVE)
icon_state = "incubator_on"
var/message = "<b>[src]</b> states, \"Warning, battery charge dump commencing.\""
src.visible_message(message)
else
var/message = "<b>[src]</b> states, \"Cannot dump energy. Battery is drained of charge already.\""
src.visible_message(message)
else
var/message = "<b>[src]</b> states, \"Cannot dump energy. No battery inserted.\""
src.visible_message(message)
if(href_list["close"])
usr << browse(null, "window=artharvester")
usr.unset_machine(src)
updateDialog()

View File

@@ -4305,6 +4305,7 @@
#include "code\modules\xenoarcheaology\anomaly_container.dm"
#include "code\modules\xenoarcheaology\boulder.dm"
#include "code\modules\xenoarcheaology\effect.dm"
#include "code\modules\xenoarcheaology\effect_master.dm"
#include "code\modules\xenoarcheaology\manuals.dm"
#include "code\modules\xenoarcheaology\misc.dm"
#include "code\modules\xenoarcheaology\sampling.dm"