Files
Yogstation/code/modules/mining/lavaland/necropolis_chests.dm
2022-06-14 18:23:36 +01:00

1602 lines
60 KiB
Plaintext

//The chests dropped by mob spawner tendrils. Also contains associated loot.
GLOBAL_LIST_EMPTY(bloodmen_list)
#define HIEROPHANT_CLUB_CARDINAL_DAMAGE 30
/obj/structure/closet/crate/necropolis
name = "necropolis chest"
desc = "It's watching you closely."
icon_state = "necrocrate"
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
/obj/structure/closet/crate/necropolis/tendril
desc = "It's watching you suspiciously."
/obj/structure/closet/crate/necropolis/tendril/PopulateContents()
var/loot = rand(1,23)
switch(loot)
if(1)
new /obj/item/shared_storage/red(src)
if(2)
new /obj/item/clothing/suit/space/hardsuit/cult(src)
if(3)
new /obj/item/soulstone/anybody(src)
if(4)
new /obj/item/reagent_containers/glass/bottle/potion/flight(src)
if(5)
new /obj/item/stack/sheet/mineral/mythril(src)
if(6)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/resonator_blast(src)
else
new /obj/item/disk/design_disk/modkit_disc/rapid_repeater(src)
if(7)
new /obj/item/rod_of_asclepius(src)
if(8)
new /obj/item/organ/heart/cursed/wizard(src)
if(9)
new /obj/item/ship_in_a_bottle(src)
if(10)
new /obj/item/reagent_containers/glass/bottle/necropolis_seed(src)
if(11)
new /obj/item/jacobs_ladder(src)
if(12)
new /obj/item/nullrod/scythe/talking(src)
if(13)
new /obj/item/nullrod/armblade(src)
if(14)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe(src)
else
new /obj/item/disk/design_disk/modkit_disc/bounty(src)
if(15)
new /obj/item/warp_cube/red(src)
if(16)
new /obj/item/organ/heart/gland/heals(src)
if(17)
new /obj/item/emberflowers(src)
if(18)
new /obj/item/voodoo(src)
if(19)
new /obj/item/reagent_containers/food/drinks/bottle/holywater/hell(src)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src)
if(20)
new /obj/item/book_of_babel(src)
if(21)
new /obj/item/borg/upgrade/modkit/lifesteal(src)
new /obj/item/bedsheet/cult(src)
if(22)
new /obj/item/clothing/neck/necklace/memento_mori(src)
if(23)
new /obj/item/rune_scimmy(src)
//KA modkit design discs
/obj/item/disk/design_disk/modkit_disc
name = "KA Mod Disk"
desc = "A design disc containing the design for a unique kinetic accelerator modkit. It's compatible with a research console."
icon_state = "datadisk1"
var/modkit_design = /datum/design/unique_modkit
/obj/item/disk/design_disk/modkit_disc/Initialize()
. = ..()
blueprints[1] = new modkit_design
/obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe
name = "Offensive Mining Explosion Mod Disk"
modkit_design = /datum/design/unique_modkit/offensive_turf_aoe
/obj/item/disk/design_disk/modkit_disc/rapid_repeater
name = "Rapid Repeater Mod Disk"
modkit_design = /datum/design/unique_modkit/rapid_repeater
/obj/item/disk/design_disk/modkit_disc/resonator_blast
name = "Resonator Blast Mod Disk"
modkit_design = /datum/design/unique_modkit/resonator_blast
/obj/item/disk/design_disk/modkit_disc/bounty
name = "Death Syphon Mod Disk"
modkit_design = /datum/design/unique_modkit/bounty
/datum/design/unique_modkit
category = list("Mining Designs", "Cyborg Upgrade Modules") //can't be normally obtained
build_type = PROTOLATHE | MECHFAB
departmental_flags = DEPARTMENTAL_FLAG_CARGO
/datum/design/unique_modkit/offensive_turf_aoe
name = "Kinetic Accelerator Offensive Mining Explosion Mod"
desc = "A device which causes kinetic accelerators to fire AoE blasts that destroy rock and damage creatures."
id = "hyperaoemod"
materials = list(/datum/material/iron = 7000, /datum/material/glass = 3000, /datum/material/silver = 3000, /datum/material/gold = 3000, /datum/material/diamond = 4000)
build_path = /obj/item/borg/upgrade/modkit/aoe/turfs/andmobs
/datum/design/unique_modkit/rapid_repeater
name = "Kinetic Accelerator Rapid Repeater Mod"
desc = "A device which greatly reduces a kinetic accelerator's cooldown on striking a living target or rock, but greatly increases its base cooldown."
id = "repeatermod"
materials = list(/datum/material/iron = 5000, /datum/material/glass = 5000, /datum/material/uranium = 8000, /datum/material/bluespace = 2000)
build_path = /obj/item/borg/upgrade/modkit/cooldown/repeater
/datum/design/unique_modkit/resonator_blast
name = "Kinetic Accelerator Resonator Blast Mod"
desc = "A device which causes kinetic accelerators to fire shots that leave and detonate resonator blasts."
id = "resonatormod"
materials = list(/datum/material/iron = 5000, /datum/material/glass = 5000, /datum/material/silver = 5000, /datum/material/uranium = 5000)
build_path = /obj/item/borg/upgrade/modkit/resonator_blasts
/datum/design/unique_modkit/bounty
name = "Kinetic Accelerator Death Syphon Mod"
desc = "A device which causes kinetic accelerators to permanently gain damage against creature types killed with it."
id = "bountymod"
materials = list(/datum/material/iron = 4000, /datum/material/silver = 4000, /datum/material/gold = 4000, /datum/material/bluespace = 4000)
reagents_list = list(/datum/reagent/blood = 40)
build_path = /obj/item/borg/upgrade/modkit/bounty
//Spooky special loot
//Rod of Asclepius
/obj/item/rod_of_asclepius
name = "\improper Rod of Asclepius"
desc = "A wooden rod about the size of your forearm with a snake carved around it, winding its way up the sides of the rod. Something about it seems to inspire in you the responsibilty and duty to help others."
icon = 'icons/obj/lavaland/artefacts.dmi'
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
icon_state = "asclepius_dormant"
var/activated = FALSE
var/usedHand
/obj/item/rod_of_asclepius/attack_self(mob/user)
if(activated)
return
if(!iscarbon(user))
to_chat(user, span_warning("The snake carving seems to come alive, if only for a moment, before returning to its dormant state, almost as if it finds you incapable of holding its oath."))
return
var/mob/living/carbon/itemUser = user
usedHand = itemUser.get_held_index_of_item(src)
if(itemUser.has_status_effect(STATUS_EFFECT_HIPPOCRATIC_OATH))
to_chat(user, span_warning("You can't possibly handle the responsibility of more than one rod!"))
return
var/failText = span_warning("The snake seems unsatisfied with your incomplete oath and returns to its previous place on the rod, returning to its dormant, wooden state. You must stand still while completing your oath!")
to_chat(itemUser, span_notice("The wooden snake that was carved into the rod seems to suddenly come alive and begins to slither down your arm! The compulsion to help others grows abnormally strong..."))
if(do_after(itemUser, 4 SECONDS, itemUser))
itemUser.say("I swear to fulfill, to the best of my ability and judgment, this covenant:", forced = "hippocratic oath")
else
to_chat(itemUser, failText)
return
if(do_after(itemUser, 2 SECONDS, itemUser))
itemUser.say("I will apply, for the benefit of the sick, all measures that are required, avoiding those twin traps of overtreatment and therapeutic nihilism.", forced = "hippocratic oath")
else
to_chat(itemUser, failText)
return
if(do_after(itemUser, 3 SECONDS, itemUser))
itemUser.say("I will remember that I remain a member of society, with special obligations to all my fellow human beings, those sound of mind and body as well as the infirm.", forced = "hippocratic oath")
else
to_chat(itemUser, failText)
return
if(do_after(itemUser, 3 SECONDS, itemUser))
itemUser.say("If I do not violate this oath, may I enjoy life and art, respected while I live and remembered with affection thereafter. May I always act so as to preserve the finest traditions of my calling and may I long experience the joy of healing those who seek my help.", forced = "hippocratic oath")
else
to_chat(itemUser, failText)
return
to_chat(itemUser, span_notice("The snake, satisfied with your oath, attaches itself and the rod to your forearm with an inseparable grip. Your thoughts seem to only revolve around the core idea of helping others, and harm is nothing more than a distant, wicked memory..."))
var/datum/status_effect/hippocraticOath/effect = itemUser.apply_status_effect(STATUS_EFFECT_HIPPOCRATIC_OATH)
effect.hand = usedHand
activated()
/obj/item/rod_of_asclepius/proc/activated()
item_flags = DROPDEL
ADD_TRAIT(src, TRAIT_NODROP, CURSED_ITEM_TRAIT)
desc = "A short wooden rod with a mystical snake inseparably gripping itself and the rod to your forearm. It flows with a healing energy that disperses amongst yourself and those around you. "
icon_state = "asclepius_active"
activated = TRUE
//Memento Mori
/obj/item/clothing/neck/necklace/memento_mori
name = "Memento Mori"
desc = "A mysterious pendant. An inscription on it says: \"Certain death tomorrow means certain life today.\""
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "memento_mori"
actions_types = list(/datum/action/item_action/hands_free/memento_mori)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/mob/living/carbon/human/active_owner
/obj/item/clothing/neck/necklace/memento_mori/item_action_slot_check(slot)
return slot == SLOT_NECK
/obj/item/clothing/neck/necklace/memento_mori/dropped(mob/user)
..()
if(active_owner)
mori()
//Just in case
/obj/item/clothing/neck/necklace/memento_mori/Destroy()
if(active_owner)
mori()
return ..()
/obj/item/clothing/neck/necklace/memento_mori/proc/memento(mob/living/carbon/human/user)
var/list/hasholos = user.hasparasites()
if(hasholos.len)
to_chat(user, span_warning("The pendant refuses to work with a guardian spirit..."))
return
if(IS_BLOODSUCKER(user))
to_chat(user, span_warning("The Memento notices your undead soul, and refuses to react.."))
return
to_chat(user, span_warning("You feel your life being drained by the pendant..."))
if(do_after(user, 4 SECONDS, user))
to_chat(user, span_notice("Your lifeforce is now linked to the pendant! You feel like removing it would kill you, and yet you instinctively know that until then, you won't die."))
ADD_TRAIT(user, TRAIT_NODEATH, "memento_mori")
ADD_TRAIT(user, TRAIT_NOHARDCRIT, "memento_mori")
ADD_TRAIT(user, TRAIT_NOCRITDAMAGE, "memento_mori")
icon_state = "memento_mori_active"
active_owner = user
/obj/item/clothing/neck/necklace/memento_mori/proc/mori()
icon_state = "memento_mori"
if(!active_owner)
return
var/mob/living/carbon/human/H = active_owner //to avoid infinite looping when dust unequips the pendant
active_owner = null
to_chat(H, span_userdanger("You feel your life rapidly slipping away from you!"))
H.dust(TRUE, TRUE)
/datum/action/item_action/hands_free/memento_mori
check_flags = NONE
name = "Memento Mori"
desc = "Bind your life to the pendant."
/datum/action/item_action/hands_free/memento_mori/Trigger()
var/obj/item/clothing/neck/necklace/memento_mori/MM = target
if(!MM.active_owner)
if(ishuman(owner))
MM.memento(owner)
else
to_chat(owner, span_warning("You try to free your lifeforce from the pendant..."))
if(do_after(owner, 4 SECONDS, owner))
MM.mori()
//Wisp Lantern
/obj/item/wisp_lantern
name = "spooky lantern"
desc = "This lantern gives off no light, but is home to a friendly wisp."
icon = 'icons/obj/lighting.dmi'
icon_state = "lantern-blue"
item_state = "lantern"
lefthand_file = 'icons/mob/inhands/equipment/mining_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi'
var/obj/effect/wisp/wisp
/obj/item/wisp_lantern/attack_self(mob/user)
if(!wisp)
to_chat(user, span_warning("The wisp has gone missing!"))
icon_state = "lantern"
return
if(wisp.loc == src)
to_chat(user, span_notice("You release the wisp. It begins to bob around your head."))
icon_state = "lantern"
wisp.orbit(user, 20)
SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Freed")
else
to_chat(user, span_notice("You return the wisp to the lantern."))
icon_state = "lantern-blue"
wisp.forceMove(src)
SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Returned")
/obj/item/wisp_lantern/Initialize()
. = ..()
wisp = new(src)
/obj/item/wisp_lantern/Destroy()
if(wisp)
if(wisp.loc == src)
qdel(wisp)
else
wisp.visible_message(span_notice("[wisp] has a sad feeling for a moment, then it passes."))
return ..()
/obj/effect/wisp
name = "friendly wisp"
desc = "Happy to light your way."
icon = 'icons/obj/lighting.dmi'
icon_state = "orb"
light_range = 7
layer = ABOVE_ALL_MOB_LAYER
var/sight_flags = SEE_MOBS
var/lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
/obj/effect/wisp/orbit(atom/thing, radius, clockwise, rotation_speed, rotation_segments, pre_rotation, lockinorbit)
. = ..()
if(ismob(thing))
RegisterSignal(thing, COMSIG_MOB_UPDATE_SIGHT, .proc/update_user_sight)
var/mob/being = thing
being.update_sight()
to_chat(thing, span_notice("The wisp enhances your vision."))
/obj/effect/wisp/stop_orbit(datum/component/orbiter/orbits)
. = ..()
if(ismob(orbits.parent))
UnregisterSignal(orbits.parent, COMSIG_MOB_UPDATE_SIGHT)
to_chat(orbits.parent, span_notice("Your vision returns to normal."))
/obj/effect/wisp/proc/update_user_sight(mob/user)
user.sight |= sight_flags
if(!isnull(lighting_alpha))
user.lighting_alpha = min(user.lighting_alpha, lighting_alpha)
//Red/Blue Cubes
/obj/item/warp_cube
name = "blue cube"
desc = "A mysterious blue cube."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "blue_cube"
var/teleport_color = "#3FBAFD"
var/obj/item/warp_cube/linked
var/teleporting = FALSE
/obj/item/warp_cube/attack_self(mob/user)
var/turf/current_location = get_turf(user)//yogs added a current location check that was totally ripped from the hand tele code honk
var/area/current_area = current_location.loc //yogs more location check stuff
if(!linked || current_area.noteleport) //yogs added noteleport
to_chat(user, "[src] fizzles uselessly.")
return
if(teleporting)
return
teleporting = TRUE
linked.teleporting = TRUE
var/turf/T = get_turf(src)
new /obj/effect/temp_visual/warp_cube(T, user, teleport_color, TRUE)
SSblackbox.record_feedback("tally", "warp_cube", 1, type)
new /obj/effect/temp_visual/warp_cube(get_turf(linked), user, linked.teleport_color, FALSE)
var/obj/effect/warp_cube/link_holder = new /obj/effect/warp_cube(T)
user.forceMove(link_holder) //mess around with loc so the user can't wander around
sleep(0.25 SECONDS)
if(QDELETED(user))
qdel(link_holder)
return
if(QDELETED(linked))
user.forceMove(get_turf(link_holder))
qdel(link_holder)
return
link_holder.forceMove(get_turf(linked))
sleep(0.25 SECONDS)
if(QDELETED(user))
qdel(link_holder)
return
teleporting = FALSE
if(!QDELETED(linked))
linked.teleporting = FALSE
user.forceMove(get_turf(link_holder))
qdel(link_holder)
/obj/item/warp_cube/red
name = "red cube"
desc = "A mysterious red cube."
icon_state = "red_cube"
teleport_color = "#FD3F48"
/obj/item/warp_cube/red/Initialize()
. = ..()
if(!linked)
var/obj/item/warp_cube/blue = new(src.loc)
linked = blue
blue.linked = src
/obj/effect/warp_cube
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE
/obj/effect/warp_cube/ex_act(severity, target)
return
//Meat Hook
/obj/item/gun/magic/hook
name = "meat hook"
desc = "Mid or feed."
ammo_type = /obj/item/ammo_casing/magic/hook
icon_state = "hook"
item_state = "chain"
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
fire_sound = 'sound/weapons/batonextend.ogg'
max_charges = 1
item_flags = NEEDS_PERMIT | NOBLUDGEON
force = 18
/obj/item/ammo_casing/magic/hook
name = "hook"
desc = "A hook."
projectile_type = /obj/item/projectile/hook
caliber = "hook"
icon_state = "hook"
/obj/item/projectile/hook
name = "hook"
icon_state = "hook"
icon = 'icons/obj/lavaland/artefacts.dmi'
pass_flags = PASSTABLE
damage = 25
armour_penetration = 100
damage_type = BRUTE
hitsound = 'sound/effects/splat.ogg'
knockdown = 30
var/chain
/obj/item/projectile/hook/fire(setAngle)
if(firer)
chain = firer.Beam(src, icon_state = "chain", time = INFINITY, maxdistance = INFINITY)
..()
//TODO: root the firer until the chain returns
/obj/item/projectile/hook/on_hit(atom/target)
. = ..()
if(ismovable(target))
var/atom/movable/A = target
if(A.anchored)
return
A.visible_message(span_danger("[A] is snagged by [firer]'s hook!"))
new /datum/forced_movement(A, get_turf(firer), 5, TRUE)
//TODO: keep the chain beamed to A
//TODO: needs a callback to delete the chain
/obj/item/projectile/hook/Destroy()
qdel(chain)
return ..()
//Immortality Talisman
/obj/item/immortality_talisman
name = "\improper Immortality Talisman"
desc = "A dread talisman that can render you completely invulnerable."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "talisman"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
actions_types = list(/datum/action/item_action/immortality)
var/cooldown = 0
/obj/item/immortality_talisman/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE, TRUE)
/datum/action/item_action/immortality
name = "Immortality"
/obj/item/immortality_talisman/attack_self(mob/user)
if(isliving(user))
var/mob/living/L = user
if(cooldown < world.time)
SSblackbox.record_feedback("amount", "immortality_talisman_uses", 1)
cooldown = world.time + 600
L.apply_status_effect(STATUS_EFFECT_VOIDED)
else
to_chat(L, span_warning("[src] is not ready yet!"))
else
to_chat(user, span_warning("Only the living can attain this power!"))
/obj/effect/immortality_talisman
name = "hole in reality"
desc = "It's shaped an awful lot like a person."
icon_state = "blank"
icon = 'icons/effects/effects.dmi'
var/vanish_description = "vanishes from reality"
var/can_destroy = TRUE
/obj/effect/immortality_talisman/Initialize(mapload, mob/new_user)
. = ..()
/obj/effect/immortality_talisman/proc/vanish(mob/user)
user.visible_message(span_danger("[user] [vanish_description], leaving a hole in [user.p_their()] place!"))
desc = "It's shaped an awful lot like [user.name]."
setDir(user.dir)
user.forceMove(src)
user.notransform = TRUE
user.status_flags |= GODMODE
can_destroy = FALSE
/obj/effect/immortality_talisman/proc/unvanish(mob/user)
user.status_flags &= ~GODMODE
user.notransform = FALSE
user.forceMove(get_turf(user))
user.visible_message(span_danger("[user] pops back into reality!"))
can_destroy = TRUE
qdel(src)
/obj/effect/immortality_talisman/attackby()
return
/obj/effect/immortality_talisman/ex_act()
return
/obj/effect/immortality_talisman/singularity_pull()
return
/obj/effect/immortality_talisman/Destroy(force)
if(!can_destroy && !force)
return QDEL_HINT_LETMELIVE
else
. = ..()
/obj/effect/immortality_talisman/void
vanish_description = "is dragged into the void"
//Shared Bag
/obj/item/shared_storage
name = "paradox bag"
desc = "Somehow, it's in two places at once."
icon = 'icons/obj/storage.dmi'
icon_state = "cultpack"
slot_flags = ITEM_SLOT_BACK
resistance_flags = INDESTRUCTIBLE
/obj/item/shared_storage/red
name = "paradox bag"
desc = "Somehow, it's in two places at once."
/obj/item/shared_storage/red/Initialize()
. = ..()
var/datum/component/storage/STR = AddComponent(/datum/component/storage/concrete)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 60
STR.max_items = 21
new /obj/item/shared_storage/blue(drop_location(), STR)
/obj/item/shared_storage/blue/Initialize(mapload, datum/component/storage/concrete/master)
. = ..()
if(!istype(master))
return INITIALIZE_HINT_QDEL
var/datum/component/storage/STR = AddComponent(/datum/component/storage, master)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 60
STR.max_items = 21
//Book of Babel
/obj/item/book_of_babel
name = "Book of Babel"
desc = "An ancient tome written in countless tongues."
icon = 'icons/obj/library.dmi'
icon_state = "book1"
w_class = 2
/obj/item/book_of_babel/attack_self(mob/user)
if(!user.can_read(src))
return FALSE
to_chat(user, span_notice("You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops."))
user.grant_all_languages()
new /obj/effect/decal/cleanable/ash(get_turf(user))
qdel(src)
//Runite Scimitar
/obj/item/rune_scimmy
name = "rune scimitar"
desc = "A curved sword smelted from an unknown metal. Looking at it gives you the otherworldly urge to pawn it off for '30k', whatever that means."
lefthand_file = 'yogstation/icons/mob/inhands/weapons/scimmy_lefthand.dmi'
righthand_file = 'yogstation/icons/mob/inhands/weapons/scimmy_righthand.dmi'
icon = 'yogstation/icons/obj/lavaland/artefacts.dmi'
icon_state = "rune_scimmy"
force = 28
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK
damtype = BRUTE
sharpness = SHARP_EDGED
hitsound = 'yogstation/sound/weapons/rs_slash.ogg'
attack_verb = list("slashed","pk'd","atk'd")
//Potion of Flight
/obj/item/reagent_containers/glass/bottle/potion
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "potionflask"
/obj/item/reagent_containers/glass/bottle/potion/flight/syndicate
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "potionflask"
/obj/item/reagent_containers/glass/bottle/potion/flight
name = "strange elixir"
desc = "A flask with an almost-holy aura emitting from it. The label on the bottle says: 'erqo'hyy tvi'rf lbh jv'atf'."
list_reagents = list(/datum/reagent/flightpotion = 5)
/obj/item/reagent_containers/glass/bottle/potion/update_icon()
if(reagents.total_volume)
icon_state = "potionflask"
else
icon_state = "potionflask_empty"
/datum/reagent/flightpotion
name = "Flight Potion"
description = "Strange mutagenic compound of unknown origins."
reagent_state = LIQUID
color = "#FFEBEB"
/datum/reagent/flightpotion/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M) && M.stat != DEAD)
var/mob/living/carbon/C = M
var/holycheck = ishumanbasic(C)
if(!(holycheck || islizard(C) || ismoth(C) || isskeleton(C) || ispreternis(C)) || (reac_volume < 5)) //humans (which are holy?), lizards, skeletons, and preterni(ises?) can get wings
if(method == INGEST && show_message)
to_chat(C, span_notice("<i>You feel nothing but a terrible aftertaste.</i>"))
return ..()
to_chat(C, span_userdanger("A terrible pain travels down your back as wings burst out!"))
C.dna.species.GiveSpeciesFlight(C)
if(holycheck)
to_chat(C, span_notice("You feel blessed!"))
ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
if(islizard(C))
to_chat(C, span_notice("You feel blessed... by... something?"))
ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
if(ismoth(C))
to_chat(C, span_notice("Your wings feel.... stronger?"))
ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
if(isskeleton(C))
to_chat(C, span_notice("Your ribcage feels... bigger?"))
ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
if(ispreternis(C))
to_chat(C, span_notice("The servos in your back feel... different?"))
ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
playsound(C.loc, 'sound/items/poster_ripped.ogg', 50, TRUE, -1)
C.adjustBruteLoss(20)
C.emote("scream")
..()
/obj/item/jacobs_ladder
name = "jacob's ladder"
desc = "A celestial ladder that violates the laws of physics."
icon = 'icons/obj/structures.dmi'
icon_state = "ladder00"
/obj/item/jacobs_ladder/attack_self(mob/user)
var/turf/T = get_turf(src)
var/ladder_x = T.x
var/ladder_y = T.y
to_chat(user, span_notice("You unfold the ladder. It extends much farther than you were expecting."))
var/last_ladder = null
for(var/i in 1 to world.maxz)
if(is_centcom_level(i) || is_reserved_level(i) || is_reebe(i) || is_away_level(i))
continue
var/turf/T2 = locate(ladder_x, ladder_y, i)
last_ladder = new /obj/structure/ladder/unbreakable/jacob(T2, null, last_ladder)
qdel(src)
// Inherit from unbreakable but don't set ID, to suppress the default Z linkage
/obj/structure/ladder/unbreakable/jacob
name = "jacob's ladder"
desc = "An indestructible celestial ladder that violates the laws of physics."
/obj/item/emberflowers
name ="emberflower bouqet"
desc ="A charming bunch of flowers, most animals seem to find the bearer amicable after momentary contact with it."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "emberflower"
/obj/item/emberflowers/attack(mob/living/simple_animal/M, mob/user)
if(M.client)
to_chat(user, span_warning("[M] is too intelligent to charm!"))
return
if(M.stat)
to_chat(user, span_warning("[M] is dead!"))
return
if(M.sentience_type != SENTIENCE_ORGANIC)
to_chat(user, span_warning("[M] cannot be charmed!"))
return
if(!do_after(user, 1.5 SECONDS, M))
return
M.visible_message(span_notice("[M] seems happy with you after exposure to the emberflowers!"))
M.add_atom_colour("#fcff57", FIXED_COLOUR_PRIORITY)
M.faction = user.faction
///Bosses
//Miniboss Miner
/obj/item/melee/transforming/cleaving_saw
name = "cleaving saw"
desc = "This saw, effective at drawing the blood of beasts, transforms into a long cleaver that makes use of centrifugal force."
force = 12
force_on = 20 //force when active
throwforce = 20
throwforce_on = 20
icon = 'icons/obj/lavaland/artefacts.dmi'
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
icon_state = "cleaving_saw"
icon_state_on = "cleaving_saw_open"
slot_flags = ITEM_SLOT_BELT
attack_verb_off = list("attacked", "sawed", "sliced", "torn", "ripped", "diced", "cut")
attack_verb_on = list("cleaved", "swiped", "slashed", "chopped")
hitsound = 'sound/weapons/bladeslice.ogg'
hitsound_on = 'sound/weapons/bladeslice.ogg'
w_class = WEIGHT_CLASS_BULKY
sharpness = SHARP_EDGED
faction_bonus_force = 30
nemesis_factions = list("mining", "boss")
var/transform_cooldown
var/swiping = FALSE
/obj/item/melee/transforming/cleaving_saw/examine(mob/user)
. = ..()
. += "<span class='notice'>It is [active ? "open, will cleave enemies in a wide arc and deal additional damage to fauna":"closed, and can be used for rapid consecutive attacks that cause fauna to bleed"].\n"+\
"Both modes will build up existing bleed effects, doing a burst of high damage if the bleed is built up high enough.\n"+\
"Transforming it immediately after an attack causes the next attack to come out faster.</span>"
/obj/item/melee/transforming/cleaving_saw/suicide_act(mob/user)
user.visible_message(span_suicide("[user] is [active ? "closing [src] on [user.p_their()] neck" : "opening [src] into [user.p_their()] chest"]! It looks like [user.p_theyre()] trying to commit suicide!"))
transform_cooldown = 0
transform_weapon(user, TRUE)
return BRUTELOSS
/obj/item/melee/transforming/cleaving_saw/transform_weapon(mob/living/user, supress_message_text)
if(transform_cooldown > world.time)
return FALSE
. = ..()
if(.)
transform_cooldown = world.time + (CLICK_CD_MELEE * 0.5)
user.changeNext_move(CLICK_CD_MELEE * 0.25)
/obj/item/melee/transforming/cleaving_saw/transform_messages(mob/living/user, supress_message_text)
if(!supress_message_text)
if(active)
to_chat(user, span_notice("You open [src]. It will now cleave enemies in a wide arc and deal additional damage to fauna."))
else
to_chat(user, span_notice("You close [src]. It will now attack rapidly and cause fauna to bleed."))
playsound(user, 'sound/magic/clockwork/fellowship_armory.ogg', 35, TRUE, frequency = 90000 - (active * 30000))
/obj/item/melee/transforming/cleaving_saw/clumsy_transform_effect(mob/living/user)
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, span_warning("You accidentally cut yourself with [src], like a doofus!"))
user.take_bodypart_damage(10)
/obj/item/melee/transforming/cleaving_saw/melee_attack_chain(mob/user, atom/target, params)
..()
if(!active)
user.changeNext_move(CLICK_CD_MELEE * 0.5) //when closed, it attacks very rapidly
/obj/item/melee/transforming/cleaving_saw/nemesis_effects(mob/living/user, mob/living/target)
var/datum/status_effect/saw_bleed/B = target.has_status_effect(STATUS_EFFECT_SAWBLEED)
if(!B)
if(!active) //This isn't in the above if-check so that the else doesn't care about active
target.apply_status_effect(STATUS_EFFECT_SAWBLEED)
else
B.add_bleed(B.bleed_buildup)
/obj/item/melee/transforming/cleaving_saw/attack(mob/living/target, mob/living/carbon/human/user)
if(!active || swiping || !target.density || get_turf(target) == get_turf(user))
if(!active)
faction_bonus_force = 0
..()
if(!active)
faction_bonus_force = initial(faction_bonus_force)
else
var/turf/user_turf = get_turf(user)
var/dir_to_target = get_dir(user_turf, get_turf(target))
swiping = TRUE
var/static/list/cleaving_saw_cleave_angles = list(0, -45, 45) //so that the animation animates towards the target clicked and not towards a side target
for(var/i in cleaving_saw_cleave_angles)
var/turf/T = get_step(user_turf, turn(dir_to_target, i))
for(var/mob/living/L in T)
if(user.Adjacent(L) && L.density)
melee_attack_chain(user, L)
swiping = FALSE
//Dragon
/obj/structure/closet/crate/necropolis/dragon
name = "dragon chest"
/obj/structure/closet/crate/necropolis/dragon/PopulateContents()
var/loot = rand(1,4)
switch(loot)
if(1)
new /obj/item/melee/ghost_sword(src)
if(2)
new /obj/item/lava_staff(src)
new /obj/item/book/granter/spell/sacredflame(src)
if(3)
new /obj/item/dragon_egg(src)
if(4)
new /obj/item/dragons_blood(src)
/obj/structure/closet/crate/necropolis/dragon/crusher
name = "firey dragon chest"
/obj/structure/closet/crate/necropolis/dragon/crusher/PopulateContents()
..()
new /obj/item/crusher_trophy/tail_spike(src)
/obj/item/melee/ghost_sword
name = "\improper spectral blade"
desc = "A rusted and dulled blade. It doesn't look like it'd do much damage. It glows weakly."
icon = 'icons/obj/weapons/swords.dmi'
icon_state = "spectral"
item_state = "spectral"
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
flags_1 = CONDUCT_1
sharpness = SHARP_EDGED
w_class = WEIGHT_CLASS_BULKY
force = 1
throwforce = 1
hitsound = 'sound/effects/ghost2.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended")
var/summon_cooldown = 0
var/list/mob/dead/observer/spirits
/obj/item/melee/ghost_sword/Initialize()
. = ..()
spirits = list()
START_PROCESSING(SSobj, src)
GLOB.poi_list |= src
AddComponent(/datum/component/butchering, 150, 90)
/obj/item/melee/ghost_sword/Destroy()
for(var/mob/dead/observer/G in spirits)
G.invisibility = GLOB.observer_default_invisibility
G.mouse_opacity = initial(G.mouse_opacity)
spirits.Cut()
STOP_PROCESSING(SSobj, src)
GLOB.poi_list -= src
. = ..()
/obj/item/melee/ghost_sword/attack_self(mob/user)
if(summon_cooldown > world.time)
to_chat(user, "You just recently called out for aid. You don't want to annoy the spirits.")
return
to_chat(user, "You call out for aid, attempting to summon spirits to your side.")
notify_ghosts("[user] is raising [user.p_their()] [src], calling for your help!",
enter_link="<a href=?src=[REF(src)];orbit=1>(Click to help)</a>",
source = user, action=NOTIFY_ORBIT, ignore_key = POLL_IGNORE_SPECTRAL_BLADE)
summon_cooldown = world.time + 600
/obj/item/melee/ghost_sword/Topic(href, href_list)
if(href_list["orbit"])
var/mob/dead/observer/ghost = usr
if(istype(ghost))
ghost.ManualFollow(src)
/obj/item/melee/ghost_sword/process()
ghost_check()
/obj/item/melee/ghost_sword/proc/recursive_orbit_collect(atom/A, list/L)
for(var/i in A.orbiters?.orbiters)
if(!isobserver(i) || (i in L))
continue
L |= i
recursive_orbit_collect(i, L)
/obj/item/melee/ghost_sword/proc/ghost_check()
var/list/mob/dead/observer/current_spirits = list()
recursive_orbit_collect(src, current_spirits)
recursive_orbit_collect(loc, current_spirits) //anything holding us
for(var/i in spirits - current_spirits)
var/mob/dead/observer/G = i
G.invisibility = GLOB.observer_default_invisibility
G.mouse_opacity = initial(G.mouse_opacity)
for(var/i in current_spirits)
var/mob/dead/observer/G = i
G.invisibility = 0
G.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
spirits = current_spirits
return length(spirits)
/obj/item/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user)
force = 0
var/ghost_counter = ghost_check()
force = clamp((ghost_counter * 4), 0, 75)
user.visible_message(span_danger("[user] strikes with the force of [ghost_counter] vengeful spirits!"))
..()
/obj/item/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
var/ghost_counter = ghost_check()
final_block_chance += clamp((ghost_counter * 5), 0, 75)
owner.visible_message(span_danger("[owner] is protected by a ring of [ghost_counter] ghosts!"))
return ..()
//Blood
/obj/item/dragons_blood
name = "bottle of dragons blood"
desc = "You're not actually going to drink this, are you?"
icon = 'icons/obj/wizard.dmi'
icon_state = "vial"
/obj/item/dragons_blood/attack_self(mob/living/carbon/human/user)
if(!istype(user))
return
var/mob/living/carbon/human/H = user
var/random = rand(1,4)
switch(random)
if(1)
to_chat(user, span_danger("Your appearance morphs to that of a very small humanoid ash dragon! You feel a little tougher, and fire now seems oddly comforting."))
H.dna.features = list("mcolor" = "A02720", "tail_lizard" = "Dark Tiger", "tail_human" = "None", "snout" = "Sharp", "horns" = "Drake", "ears" = "None", "wings" = "None", "frills" = "None", "spines" = "Long", "body_markings" = "Dark Tiger Body", "legs" = "Digitigrade Legs")
H.set_species(/datum/species/lizard/draconid)
H.eye_color = "fee5a3"
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.updateappearance()
if(2)
to_chat(user, span_danger("Your flesh begins to melt! Miraculously, you seem fine otherwise."))
H.set_species(/datum/species/skeleton)
if(3)
to_chat(user, span_danger("Power courses through you! You can now shift your form at will."))
if(user.mind)
var/obj/effect/proc_holder/spell/targeted/shapeshift/dragon/D = new
user.mind.AddSpell(D)
if(4)
to_chat(user, span_danger("You feel like you could walk straight through lava now."))
H.weather_immunities |= "lava"
playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1)
qdel(src)
/datum/disease/transformation/dragon
name = "dragon transformation"
cure_text = "nothing"
cures = list(/datum/reagent/medicine/adminordrazine)
agent = "dragon's blood"
desc = "What do dragons have to do with Space Station 13?"
stage_prob = 20
severity = DISEASE_SEVERITY_BIOHAZARD
visibility_flags = 0
stage1 = list("Your bones ache.")
stage2 = list("Your skin feels scaly.")
stage3 = list(span_danger("You have an overwhelming urge to terrorize some peasants."), span_danger("Your teeth feel sharper."))
stage4 = list(span_danger("Your blood burns."))
stage5 = list(span_danger("You're a fucking dragon. However, any previous allegiances you held still apply. It'd be incredibly rude to eat your still human friends for no reason."))
new_form = /mob/living/simple_animal/hostile/megafauna/dragon/lesser
//Lava Staff
/obj/item/lava_staff
name = "staff of lava"
desc = "The ability to fill the emergency shuttle with lava. What more could you want out of life?"
icon_state = "staffofstorms"
item_state = "staffofstorms"
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
icon = 'icons/obj/guns/magic.dmi'
slot_flags = ITEM_SLOT_BACK
w_class = WEIGHT_CLASS_BULKY
force = 25
damtype = BURN
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
hitsound = 'sound/weapons/sear.ogg'
var/turf_type = /turf/open/lava/smooth
var/transform_string = "lava"
var/reset_turf_type = /turf/open/floor/plating/asteroid/basalt
var/reset_string = "basalt"
var/create_cooldown = 10 SECONDS
var/create_delay = 3 SECONDS
var/reset_cooldown = 5 SECONDS
var/timer = 0
var/static/list/banned_turfs = typecacheof(list(/turf/open/space/transit, /turf/closed))
/obj/item/lava_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(timer > world.time)
return
if(is_type_in_typecache(target, banned_turfs))
return
if(target in view(user.client.view, get_turf(user)))
var/turf/open/T = get_turf(target)
if(!istype(T))
return
if(!istype(T, turf_type))
var/obj/effect/temp_visual/lavastaff/L = new /obj/effect/temp_visual/lavastaff(T)
L.alpha = 0
animate(L, alpha = 255, time = create_delay)
user.visible_message(span_danger("[user] points [src] at [T]!"))
timer = world.time + create_delay + 1
if(do_after(user, create_delay, T))
var/old_name = T.name
if(T.TerraformTurf(turf_type, flags = CHANGETURF_INHERIT_AIR))
user.visible_message(span_danger("[user] turns \the [old_name] into [transform_string]!"))
message_admins("[ADMIN_LOOKUPFLW(user)] fired the lava staff at [ADMIN_VERBOSEJMP(T)]")
log_game("[key_name(user)] fired the lava staff at [AREACOORD(T)].")
timer = world.time + create_cooldown
playsound(T,'sound/magic/fireball.ogg', 200, 1)
else
timer = world.time
qdel(L)
else
var/old_name = T.name
if(T.TerraformTurf(reset_turf_type, flags = CHANGETURF_INHERIT_AIR))
user.visible_message(span_danger("[user] turns \the [old_name] into [reset_string]!"))
timer = world.time + reset_cooldown
playsound(T,'sound/magic/fireball.ogg', 200, 1)
/obj/effect/temp_visual/lavastaff
icon_state = "lavastaff_warn"
duration = 50
//Dragon Egg
/obj/item/dragon_egg
name = "dragon's egg"
desc = "A large egg-shaped rock. It's cold to the touch..."
icon = 'icons/mob/lavaland/lavaland_monsters.dmi'
icon_state = "large_egg"
color = "#2C2C2C"
/obj/item/dragon_egg/burn()
visible_message(span_boldwarning("[src] suddenly begins to glow red and starts violently shaking!"))
name = "heated dragon's egg"
desc = "A large egg seemingly made out of rock. It's red-hot and seems to be shaking!"
color = "#990000"
extinguish()
resistance_flags = LAVA_PROOF | FIRE_PROOF
addtimer(CALLBACK(src, .proc/hatch), 20 SECONDS)
/obj/item/dragon_egg/proc/hatch()
visible_message(span_boldwarning("[src] suddenly cracks apart, revealing a tiny ash drake!"))
new /mob/living/simple_animal/hostile/drakeling(get_turf(src))
qdel(src)
//Bubblegum
/obj/structure/closet/crate/necropolis/bubblegum
name = "bubblegum chest"
/obj/structure/closet/crate/necropolis/bubblegum/PopulateContents()
new /obj/item/clothing/suit/space/hostile_environment(src)
new /obj/item/clothing/head/helmet/space/hostile_environment(src)
var/loot = rand(1,2)
switch(loot)
if(1)
new /obj/item/melee/knuckles(src)
if(2)
new /obj/item/clothing/gloves/bracer/cuffs(src)
/obj/structure/closet/crate/necropolis/bubblegum/crusher
name = "bloody bubblegum chest"
/obj/structure/closet/crate/necropolis/bubblegum/crusher/PopulateContents()
..()
new /obj/item/crusher_trophy/demon_claws(src)
/obj/item/mayhem
name = "mayhem in a bottle"
desc = "A magically infused bottle of blood, the scent of which will drive anyone nearby into a murderous frenzy."
icon = 'icons/obj/wizard.dmi'
icon_state = "vial"
/obj/item/mayhem/attack_self(mob/user)
for(var/mob/living/carbon/human/H in range(7,user))
var/obj/effect/mine/pickup/bloodbath/B = new(H)
INVOKE_ASYNC(B, /obj/effect/mine/pickup/bloodbath/.proc/mineEffect, H)
to_chat(user, span_notice("You shatter the bottle!"))
playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1)
message_admins(span_adminnotice("[ADMIN_LOOKUPFLW(user)] has activated a bottle of mayhem!"))
log_combat(user, null, "activated a bottle of mayhem", src)
qdel(src)
/obj/item/blood_contract
name = "blood contract"
icon = 'icons/obj/wizard.dmi'
icon_state = "scroll2"
color = "#FF0000"
desc = "Mark your target for death."
var/used = FALSE
/obj/item/blood_contract/attack_self(mob/user)
if(used)
return
used = TRUE
var/list/da_list = list()
for(var/I in GLOB.alive_mob_list & GLOB.player_list)
var/mob/living/L = I
da_list[L.real_name] = L
var/choice = input(user,"Who do you want dead?","Choose Your Victim") as null|anything in da_list
choice = da_list[choice]
if(!choice)
used = FALSE
return
if(!(isliving(choice)))
to_chat(user, "[choice] is already dead!")
used = FALSE
return
if(choice == user)
to_chat(user, "You feel like writing your own name into a cursed death warrant would be unwise.")
used = FALSE
return
var/mob/living/L = choice
message_admins(span_adminnotice("[ADMIN_LOOKUPFLW(L)] has been marked for death by [ADMIN_LOOKUPFLW(user)]!"))
var/datum/antagonist/blood_contract/A = new
L.mind.add_antag_datum(A)
log_combat(user, L, "took out a blood contract on", src)
qdel(src)
#define COOLDOWN 150
#define COOLDOWN_HUMAN 100
#define COOLDOWN_ANIMAL 60
/obj/item/melee/knuckles
name = "bloody knuckles"
desc = "Knuckles born of a desire for violence. Made to ensure their victims stay in the fight until there's a winner."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "bloodyknuckle"
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
item_state = "knuckles"
w_class = WEIGHT_CLASS_SMALL
force = 18
var/next_reach = 0
var/next_grip = 0
var/next_knuckle = 0
attack_verb = list("thrashed", "pummeled", "walloped")
actions_types = list(/datum/action/item_action/reach, /datum/action/item_action/visegrip)
/obj/item/melee/knuckles/afterattack(mob/living/target, mob/living/user, proximity)
var/mob/living/L = target
if (proximity)
if(L.has_status_effect(STATUS_EFFECT_KNUCKLED))
L.apply_status_effect(/datum/status_effect/roots)
return
if(next_knuckle > world.time)
to_chat(user, span_warning("The knuckles aren't ready to mark yet."))
return
else
L.apply_status_effect(STATUS_EFFECT_KNUCKLED)
if(ishuman(L))
next_knuckle = world.time + COOLDOWN_HUMAN
return
next_knuckle = world.time + COOLDOWN_ANIMAL
/obj/item/melee/knuckles/ui_action_click(mob/living/user, action)
var/mob/living/U = user
if(istype(action, /datum/action/item_action/reach))
if(next_reach > world.time)
to_chat(U, span_warning("You can't do that yet!"))
return
var/valid_reaching = FALSE
for(var/mob/living/L in view(7, U))
for(var/obj/effect/decal/cleanable/B in range(0,L))
if(istype(B, /obj/effect/decal/cleanable/blood )|| istype(B, /obj/effect/decal/cleanable/trail_holder))
valid_reaching = TRUE
L.apply_status_effect(STATUS_EFFECT_KNUCKLED)
if(!valid_reaching)
to_chat(U, span_warning("There's nobody to use this on!"))
return
next_reach = world.time + COOLDOWN
else if(istype(action, /datum/action/item_action/visegrip))
if(next_grip > world.time)
to_chat(U, span_warning("You can't do that yet!"))
return
var/valid_casting = FALSE
for(var/mob/living/L in view(8, U))
if(L.has_status_effect(STATUS_EFFECT_KNUCKLED))
valid_casting = TRUE
L.apply_status_effect(/datum/status_effect/roots)
if(!valid_casting)
to_chat(U, span_warning("There's nobody to use this on!"))
return
next_grip = world.time + COOLDOWN
#undef COOLDOWN
#undef COOLDOWN_HUMAN
#undef COOLDOWN_ANIMAL
//Colossus
/obj/structure/closet/crate/necropolis/colossus
name = "colossus chest"
/obj/structure/closet/crate/necropolis/colossus/bullet_act(obj/item/projectile/P)
if(istype(P, /obj/item/projectile/colossus))
return BULLET_ACT_FORCE_PIERCE
return ..()
/obj/structure/closet/crate/necropolis/colossus/PopulateContents()
var/list/choices = subtypesof(/obj/machinery/anomalous_crystal)
var/random_crystal = pick(choices)
new random_crystal(src)
new /obj/item/organ/vocal_cords/colossus(src)
new /obj/item/clothing/glasses/godeye(src)
/obj/structure/closet/crate/necropolis/colossus/crusher
name = "angelic colossus chest"
/obj/structure/closet/crate/necropolis/colossus/crusher/PopulateContents()
..()
new /obj/item/crusher_trophy/blaster_tubes(src)
//Hierophant
/obj/item/hierophant_club
name = "hierophant club"
desc = "The strange technology of this large club allows various nigh-magical feats. It used to beat you, but now you can set the beat."
icon_state = "hierophant_club_ready_beacon"
item_state = "hierophant_club_ready_beacon"
icon = 'icons/obj/lavaland/artefacts.dmi'
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
slot_flags = ITEM_SLOT_BACK
w_class = WEIGHT_CLASS_BULKY
force = 15
attack_verb = list("clubbed", "beat", "pummeled")
hitsound = 'sound/weapons/sonic_jackhammer.ogg'
actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire)
var/z_level_check = TRUE //Whether or not it checks for mining z level
var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is
var/chaser_cooldown = 81 //how long the cooldown between firing chasers at mobs is
var/chaser_timer = 0 //what our current chaser cooldown is
var/chaser_speed = 0.8 //how fast our chasers are
var/timer = 0 //what our current cooldown is
var/blast_range = 13 //how long the cardinal blast's walls are
var/obj/effect/hierophant/beacon //the associated beacon we teleport to
var/teleporting = FALSE //if we ARE teleporting
var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets
/obj/item/hierophant_club/examine(mob/user)
. = ..()
. += "[span_hierophant_warning("The[beacon ? " beacon is not currently":"re is a beacon"] attached.")]"
/obj/item/hierophant_club/suicide_act(mob/living/user)
say("Xverwpsgexmrk...", forced = "hierophant club suicide")
user.visible_message(span_suicide("[user] holds [src] into the air! It looks like [user.p_theyre()] trying to commit suicide!"))
new/obj/effect/temp_visual/hierophant/telegraph(get_turf(user))
playsound(user,'sound/machines/airlockopen.ogg', 75, TRUE)
user.visible_message("[span_hierophant_warning("[user] fades out, leaving [user.p_their()] belongings behind!")]")
for(var/obj/item/I in user)
if(I != src)
user.dropItemToGround(I)
for(var/turf/T in RANGE_TURFS(1, user))
var/obj/effect/temp_visual/hierophant/blast/B = new(T, user, TRUE)
B.damage = 0
user.dropItemToGround(src) //Drop us last, so it goes on top of their stuff
qdel(user)
/obj/item/hierophant_club/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
var/turf/T = get_turf(target)
if(!T || timer > world.time)
return
if(!is_mining_level(T.z) && z_level_check)
to_chat(user, span_warning("The club fizzles weakly, it seem its power doesn't reach this area.") )
return
calculate_anger_mod(user)
timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown
if(proximity_flag)
INVOKE_ASYNC(src, .proc/aoe_burst, T, user)
log_combat(user, target, "fired 3x3 blast at", src)
else
if(ismineralturf(target) && get_dist(user, target) < 6) //target is minerals, we can hit it(even if we can't see it)
INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user)
timer = world.time + cooldown_time
else if(target in view(5, get_turf(user))) //if the target is in view, hit it
timer = world.time + cooldown_time
if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
chaser_timer = world.time + chaser_cooldown
var/obj/effect/temp_visual/hierophant/chaser/C = new(get_turf(user), user, target, chaser_speed, friendly_fire_check)
C.damage = 30
C.monster_damage_boost = FALSE
log_combat(user, target, "fired a chaser at", src)
else
INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user) //otherwise, just do cardinal blast
log_combat(user, target, "fired cardinal blast at", src)
else
to_chat(user, span_warning("That target is out of range!") )
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
/obj/item/hierophant_club/proc/calculate_anger_mod(mob/user) //we get stronger as the user loses health
chaser_cooldown = initial(chaser_cooldown)
cooldown_time = initial(cooldown_time)
chaser_speed = initial(chaser_speed)
blast_range = initial(blast_range)
if(isliving(user))
var/mob/living/L = user
var/health_percent = L.health / L.maxHealth
chaser_cooldown += round(health_percent * 20) //two tenths of a second for each missing 10% of health
cooldown_time += round(health_percent * 10) //one tenth of a second for each missing 10% of health
chaser_speed = max(chaser_speed + health_percent, 0.5) //one tenth of a second faster for each missing 10% of health
blast_range -= round(health_percent * 10) //one additional range for each missing 10% of health
/obj/item/hierophant_club/update_icon()
icon_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !QDELETED(beacon)) ? "":"_beacon"]"
item_state = icon_state
if(ismob(loc))
var/mob/M = loc
M.update_inv_hands()
M.update_inv_back()
/obj/item/hierophant_club/proc/prepare_icon_update()
update_icon()
sleep(timer - world.time)
update_icon()
/obj/item/hierophant_club/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_unfriendly_fire)) //toggle friendly fire...
friendly_fire_check = !friendly_fire_check
to_chat(user, span_warning("You toggle friendly fire [friendly_fire_check ? "off":"on"]!"))
return
if(timer > world.time)
return
if(!user.is_holding(src)) //you need to hold the staff to teleport
to_chat(user, span_warning("You need to hold the club in your hands to [beacon ? "teleport with it":"detach the beacon"]!"))
return
if(!beacon || QDELETED(beacon))
if(isturf(user.loc))
user.visible_message("[span_hierophant_warning("[user] starts fiddling with [src]'s pommel...")]", \
span_notice("You start detaching the hierophant beacon..."))
timer = world.time + 5.1 SECONDS
INVOKE_ASYNC(src, .proc/prepare_icon_update)
if(do_after(user, 5 SECONDS, user) && !beacon)
var/turf/T = get_turf(user)
playsound(T,'sound/magic/blind.ogg', 200, 1, -4)
new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, user)
beacon = new/obj/effect/hierophant(T)
user.update_action_buttons_icon()
user.visible_message("[span_hierophant_warning("[user] places a strange machine beneath [user.p_their()] feet!")]", \
"[span_hierophant("You detach the hierophant beacon, allowing you to teleport yourself and any allies to it at any time!")]\n\
[span_notice("You can remove the beacon to place it again by striking it with the club.")]")
else
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
else
to_chat(user, span_warning("You need to be on solid ground to detach the beacon!"))
return
if(get_dist(user, beacon) <= 2) //beacon too close abort
to_chat(user, span_warning("You are too close to the beacon to teleport to it!"))
return
if(is_blocked_turf(get_turf(beacon), TRUE))
to_chat(user, span_warning("The beacon is blocked by something, preventing teleportation!"))
return
if(!isturf(user.loc))
to_chat(user, span_warning("You don't have enough space to teleport from here!"))
return
teleporting = TRUE //start channel
user.update_action_buttons_icon()
user.visible_message("[span_hierophant_warning("[user] starts to glow faintly...")]")
timer = world.time + 5 SECONDS
INVOKE_ASYNC(src, .proc/prepare_icon_update)
beacon.icon_state = "hierophant_tele_on"
var/obj/effect/temp_visual/hierophant/telegraph/edge/TE1 = new /obj/effect/temp_visual/hierophant/telegraph/edge(user.loc)
var/obj/effect/temp_visual/hierophant/telegraph/edge/TE2 = new /obj/effect/temp_visual/hierophant/telegraph/edge(beacon.loc)
if(do_after(user, 4 SECONDS, user) && user && beacon)
var/turf/T = get_turf(beacon)
var/turf/source = get_turf(user)
if(is_blocked_turf(T, TRUE))
teleporting = FALSE
to_chat(user, span_warning("The beacon is blocked by something, preventing teleportation!"))
user.update_action_buttons_icon()
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
beacon.icon_state = "hierophant_tele_off"
return
new /obj/effect/temp_visual/hierophant/telegraph(T, user)
new /obj/effect/temp_visual/hierophant/telegraph(source, user)
playsound(T,'sound/magic/wand_teleport.ogg', 200, 1)
playsound(source,'sound/machines/airlockopen.ogg', 200, 1)
if(!do_after(user, 0.3 SECONDS, user) || !user || !beacon || QDELETED(beacon)) //no walking away shitlord
teleporting = FALSE
if(user)
user.update_action_buttons_icon()
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
if(beacon)
beacon.icon_state = "hierophant_tele_off"
return
if(is_blocked_turf(T, TRUE))
teleporting = FALSE
to_chat(user, span_warning("The beacon is blocked by something, preventing teleportation!"))
user.update_action_buttons_icon()
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
beacon.icon_state = "hierophant_tele_off"
return
user.log_message("teleported self from [AREACOORD(source)] to [beacon]", LOG_GAME)
new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, user)
new /obj/effect/temp_visual/hierophant/telegraph/teleport(source, user)
for(var/t in RANGE_TURFS(1, T))
var/obj/effect/temp_visual/hierophant/blast/B = new /obj/effect/temp_visual/hierophant/blast(t, user, TRUE) //blasts produced will not hurt allies
B.damage = 30
for(var/t in RANGE_TURFS(1, source))
var/obj/effect/temp_visual/hierophant/blast/B = new /obj/effect/temp_visual/hierophant/blast(t, user, TRUE) //but absolutely will hurt enemies
B.damage = 30
for(var/mob/living/L in range(1, source))
INVOKE_ASYNC(src, .proc/teleport_mob, source, L, T, user) //regardless, take all mobs near us along
sleep(0.6 SECONDS) //at this point the blasts detonate
if(beacon)
beacon.icon_state = "hierophant_tele_off"
else
qdel(TE1)
qdel(TE2)
timer = world.time
INVOKE_ASYNC(src, .proc/prepare_icon_update)
if(beacon)
beacon.icon_state = "hierophant_tele_off"
teleporting = FALSE
if(user)
user.update_action_buttons_icon()
/obj/item/hierophant_club/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user)
var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster
if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to, TRUE))
return
animate(M, alpha = 0, time = 0.2 SECONDS, easing = EASE_OUT) //fade out
sleep(0.1 SECONDS)
if(!M)
return
M.visible_message("[span_hierophant_warning("[M] fades out!")]")
sleep(0.2 SECONDS)
if(!M)
return
M.forceMove(turf_to_teleport_to)
sleep(0.1 SECONDS)
if(!M)
return
animate(M, alpha = 255, time = 0.2 SECONDS, easing = EASE_IN) //fade IN
sleep(0.1 SECONDS)
if(!M)
return
M.visible_message("[span_hierophant_warning("[M] fades in!")]")
if(user != M)
log_combat(user, M, "teleported", null, "from [AREACOORD(source)]")
/obj/item/hierophant_club/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
if(!T)
return
new /obj/effect/temp_visual/hierophant/telegraph/cardinal(T, user)
playsound(T,'sound/effects/bin_close.ogg', 200, 1)
sleep(0.2 SECONDS)
var/obj/effect/temp_visual/hierophant/blast/B = new(T, user, friendly_fire_check)
B.damage = HIEROPHANT_CLUB_CARDINAL_DAMAGE
B.monster_damage_boost = FALSE
for(var/d in GLOB.cardinals)
INVOKE_ASYNC(src, .proc/blast_wall, T, d, user)
/obj/item/hierophant_club/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long
if(!T)
return
var/range = blast_range
var/turf/previousturf = T
var/turf/J = get_step(previousturf, dir)
for(var/i in 1 to range)
if(!J)
return
var/obj/effect/temp_visual/hierophant/blast/B = new(J, user, friendly_fire_check)
B.damage = HIEROPHANT_CLUB_CARDINAL_DAMAGE
B.monster_damage_boost = FALSE
previousturf = J
J = get_step(previousturf, dir)
/obj/item/hierophant_club/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target
if(!T)
return
new /obj/effect/temp_visual/hierophant/telegraph(T, user)
playsound(T,'sound/effects/bin_close.ogg', 200, 1)
sleep(0.2 SECONDS)
for(var/t in RANGE_TURFS(1, T))
var/obj/effect/temp_visual/hierophant/blast/B = new(t, user, friendly_fire_check)
B.damage = 15 //keeps monster damage boost due to lower damage
/obj/item/hierophant_antenna
name = "hierophant's antenna"
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "hierophant_antenna"
item_state = "hierophant_antenna"
desc = "Extends the range of the herald's power."
/obj/item/hierophant_club/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/hierophant_antenna))
if(z_level_check)
z_level_check = FALSE
desc += " It has an ominous antenna attached."
qdel(I)
else
to_chat(user, span_warning("The herald's power already reaches this club!"))
return TRUE
else
return ..()
/obj/item/hierophant_club/station
z_level_check = FALSE
//Stalwart
/obj/structure/closet/crate/sphere/stalwart
name = "silvery capsule"
desc = "It feels cold to the touch..."
/obj/structure/closet/crate/sphere/stalwart/PopulateContents()
new /obj/item/gun/energy/plasmacutter/adv/robocutter
/obj/item/gun/energy/plasmacutter/adv/robocutter
name = "energized powercutter"
desc = "Ripped out of an ancient machine, this self-recharging cutter is unmatched."
fire_delay = 4
icon = 'icons/obj/guns/energy.dmi'
icon_state = "robocutter"
selfcharge = 1
//Just some minor stuff
/obj/structure/closet/crate/necropolis/puzzle
name = "puzzling chest"
/obj/structure/closet/crate/necropolis/puzzle/PopulateContents()
var/loot = rand(1,3)
switch(loot)
if(1)
new /obj/item/soulstone/anybody(src)
if(2)
new /obj/item/wisp_lantern(src)
if(3)
new /obj/item/prisoncube(src)
//Legion
/obj/item/organ/grandcore
name = "grand core"
desc = "The source of the Legion's powers. Though mostly expended, you might be able to get some use out of it."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "grandcore"
slot = "hivecore"
w_class = WEIGHT_CLASS_SMALL
decay_factor = 0
actions_types = list(/datum/action/item_action/organ_action/threebloodlings)
/obj/item/organ/grandcore/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target)
if(H == user && istype(H))
playsound(user,'sound/effects/singlebeat.ogg',40,1)
user.temporarilyRemoveItemFromInventory(src, TRUE)
Insert(user)
/obj/item/organ/grandcore/Insert(mob/living/carbon/H, special = 0)
..()
H.faction |= "blooded"
H.AddSpell (new /obj/effect/proc_holder/spell/targeted/touch/raise)
H.AddSpell (new /obj/effect/proc_holder/spell/aoe_turf/horde)
if(NOBLOOD in H.dna.species.species_traits)
to_chat(owner, "<span class ='userdanger'>Despite lacking blood, you were able to take in the grand core. You will pay for your power in killer headaches!</span>")
else
to_chat(owner, "<span class ='userdanger'>You've taken in the grand core, allowing you to control minions at the cost of your blood!</span>")
/obj/item/organ/grandcore/Remove(mob/living/carbon/H, special = 0)
H.faction -= "blooded"
H.RemoveSpell (/obj/effect/proc_holder/spell/targeted/touch/raise, /obj/effect/proc_holder/spell/aoe_turf/horde)
H.RemoveSpell (new /obj/effect/proc_holder/spell/aoe_turf/horde)
..()
/datum/action/item_action/organ_action/threebloodlings
name = "Summon bloodlings"
desc = "Summon a conjure a few bloodlings at the cost of 13% blood (8 brain damage for those without blood)."
var/next_expulsion = 0
var/cooldown = 10 //wheres the risk if it has a reasonable cooldown?
/datum/action/item_action/organ_action/threebloodlings/Trigger()
var/mob/living/carbon/H = owner
. = ..()
if(next_expulsion > world.time)
to_chat(owner, span_warning("Don't spill your blood so haphazardly!"))
return
if(NOBLOOD in H.dna.species.species_traits)
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 8) //brain damage wont stop you from running away so opting for that instead of poison or breath damage
to_chat(H, "<span class ='userdanger'>Your head pounds as you produce bloodlings!</span>")
else
to_chat(H, "<span class ='userdanger'>You spill your blood, and it comes to life as bloodlings!</span>")
H.blood_volume -= 70 //like 13% of your blood taken
spawn_atom_to_turf(/mob/living/simple_animal/hostile/asteroid/hivelordbrood/bloodling, owner, 3, TRUE) //think 1 in 4 is a good chance of not being targeted by fauna
next_expulsion = world.time + cooldown