mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-15 17:13:46 +01:00
Merge remote-tracking branch 'upstream/master' into botany-rework
This commit is contained in:
@@ -727,7 +727,7 @@
|
||||
ranged = 1
|
||||
sentience_type = SENTIENCE_MINEBOT
|
||||
ranged_message = "shoots"
|
||||
ranged_cooldown_cap = 3
|
||||
ranged_cooldown_time = 30
|
||||
projectiletype = /obj/item/projectile/kinetic
|
||||
projectilesound = 'sound/weapons/Gunshot4.ogg'
|
||||
speak_emote = list("states")
|
||||
@@ -978,10 +978,10 @@
|
||||
name = "minebot cooldown upgrade"
|
||||
|
||||
/obj/item/device/mine_bot_ugprade/cooldown/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user)
|
||||
if(M.ranged_cooldown_cap != initial(M.ranged_cooldown_cap))
|
||||
if(M.ranged_cooldown_time != initial(M.ranged_cooldown_time))
|
||||
to_chat(user, "[M] already has a decreased weapon cooldown!")
|
||||
return
|
||||
M.ranged_cooldown_cap = 1
|
||||
M.ranged_cooldown_time = 10
|
||||
to_chat(user, "You upgrade [M]'s ranged weaponry, reducing its cooldown.")
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/obj/structure/flora/ash
|
||||
gender = PLURAL
|
||||
icon = 'icons/obj/lavaland/ash_flora.dmi'
|
||||
icon_state = "l_mushroom"
|
||||
name = "large mushrooms"
|
||||
desc = "A number of large mushrooms, covered in a faint layer of ash and what can only be spores."
|
||||
var/harvested_name = "shortened mushrooms"
|
||||
var/harvested_desc = "Some quickly regrowing mushrooms, formerly known to be quite large."
|
||||
var/needs_sharp_harvest = TRUE
|
||||
var/harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/shavings
|
||||
var/harvest_amount_low = 1
|
||||
var/harvest_amount_high = 3
|
||||
var/harvest_time = 60
|
||||
var/harvest_message_low = "You pick a mushroom, but fail to collect many shavings from its cap."
|
||||
var/harvest_message_med = "You pick a mushroom, carefully collecting the shavings from its cap."
|
||||
var/harvest_message_high = "You harvest and collect shavings from several mushroom caps."
|
||||
var/harvested = FALSE
|
||||
var/base_icon
|
||||
var/regrowth_time_low = 4800
|
||||
var/regrowth_time_high = 8400
|
||||
|
||||
/obj/structure/flora/ash/New()
|
||||
..()
|
||||
base_icon = "[icon_state][rand(1, 4)]"
|
||||
icon_state = base_icon
|
||||
if(prob(15))
|
||||
harvest(null, TRUE)
|
||||
|
||||
/obj/structure/flora/ash/proc/harvest(user, no_drop)
|
||||
if(harvested)
|
||||
return 0
|
||||
if(!no_drop)
|
||||
var/rand_harvested = rand(harvest_amount_low, harvest_amount_high)
|
||||
if(rand_harvested)
|
||||
if(user)
|
||||
var/msg = harvest_message_med
|
||||
if(rand_harvested == harvest_amount_low)
|
||||
msg = harvest_message_low
|
||||
else if(rand_harvested == harvest_amount_high)
|
||||
msg = harvest_message_high
|
||||
to_chat(user, "<span class='notice'>[msg]</span>")
|
||||
for(var/i in 1 to rand_harvested)
|
||||
new harvest(get_turf(src))
|
||||
icon_state = "[base_icon]p"
|
||||
name = harvested_name
|
||||
desc = harvested_desc
|
||||
harvested = TRUE
|
||||
addtimer(src, "regrow", rand(regrowth_time_low, regrowth_time_high))
|
||||
return 1
|
||||
|
||||
/obj/structure/flora/ash/proc/regrow()
|
||||
icon_state = base_icon
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
harvested = FALSE
|
||||
|
||||
/obj/structure/flora/ash/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(!harvested && needs_sharp_harvest && W.sharp)
|
||||
user.visible_message("<span class='notice'>[user] starts to harvest from [src] with [W].</span>","<span class='notice'>You begin to harvest from [src] with [W].</span>")
|
||||
if(do_after(user, harvest_time, target = src))
|
||||
harvest(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/flora/ash/attack_hand(mob/user)
|
||||
if(!harvested && !needs_sharp_harvest)
|
||||
user.visible_message("<span class='notice'>[user] starts to harvest from [src].</span>","<span class='notice'>You begin to harvest from [src].</span>")
|
||||
if(do_after(user, harvest_time, target = src))
|
||||
harvest(user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ash/tall_shroom //exists only so that the spawning check doesn't allow these spawning near other things
|
||||
regrowth_time_low = 4200
|
||||
|
||||
/obj/structure/flora/ash/leaf_shroom
|
||||
icon_state = "s_mushroom"
|
||||
name = "leafy mushrooms"
|
||||
desc = "A number of mushrooms, each of which surrounds a greenish sporangium with a number of leaf-like structures."
|
||||
harvested_name = "leafless mushrooms"
|
||||
harvested_desc = "A bunch of formerly-leafed mushrooms, with their sporangiums exposed. Scandalous?"
|
||||
harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_leaf
|
||||
needs_sharp_harvest = FALSE
|
||||
harvest_amount_high = 4
|
||||
harvest_time = 20
|
||||
harvest_message_low = "You pluck a single, suitable leaf."
|
||||
harvest_message_med = "You pluck a number of leaves, leaving a few unsuitable ones."
|
||||
harvest_message_high = "You pluck quite a lot of suitable leaves."
|
||||
regrowth_time_low = 2400
|
||||
regrowth_time_high = 6000
|
||||
|
||||
/obj/structure/flora/ash/cap_shroom
|
||||
icon_state = "r_mushroom"
|
||||
name = "tall mushrooms"
|
||||
desc = "Several mushrooms, the larger of which have a ring of conks at the midpoint of their stems."
|
||||
harvested_name = "small mushrooms"
|
||||
harvested_desc = "Several small mushrooms near the stumps of what likely were larger mushrooms."
|
||||
harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_cap
|
||||
harvest_amount_high = 4
|
||||
harvest_time = 50
|
||||
harvest_message_low = "You slice the cap off of a mushroom."
|
||||
harvest_message_med = "You slice off a few conks from the larger mushrooms."
|
||||
harvest_message_high = "You slice off a number of caps and conks from these mushrooms."
|
||||
regrowth_time_low = 3000
|
||||
regrowth_time_high = 5400
|
||||
|
||||
/obj/structure/flora/ash/stem_shroom
|
||||
icon_state = "t_mushroom"
|
||||
name = "numerous mushrooms"
|
||||
desc = "A large number of mushrooms, some of which have long, fleshy stems. They're radiating light!"
|
||||
luminosity = 1
|
||||
harvested_name = "tiny mushrooms"
|
||||
harvested_desc = "A few tiny mushrooms around larger stumps. You can already see them growing back."
|
||||
harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_stem
|
||||
harvest_amount_high = 4
|
||||
harvest_time = 40
|
||||
harvest_message_low = "You pick and slice the cap off of a mushroom, leaving the stem."
|
||||
harvest_message_med = "You pick and decapitate several mushrooms for their stems."
|
||||
harvest_message_high = "You acquire a number of stems from these mushrooms."
|
||||
regrowth_time_low = 3000
|
||||
regrowth_time_high = 6000
|
||||
|
||||
/obj/structure/flora/ash/cacti
|
||||
icon_state = "cactus"
|
||||
name = "fruiting cacti"
|
||||
desc = "Several prickly cacti, brimming with ripe fruit and covered in a thin layer of ash."
|
||||
harvested_name = "cacti"
|
||||
harvested_desc = "A bunch of prickly cacti. You can see fruits slowly growing beneath the covering of ash."
|
||||
harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/cactus_fruit
|
||||
needs_sharp_harvest = FALSE
|
||||
harvest_amount_high = 2
|
||||
harvest_time = 10
|
||||
harvest_message_low = "You pick a cactus fruit."
|
||||
harvest_message_med = "You pick several cactus fruit." //shouldn't show up, because you can't get more than two
|
||||
harvest_message_high = "You pick a pair of cactus fruit."
|
||||
regrowth_time_low = 4800
|
||||
regrowth_time_high = 7200
|
||||
|
||||
/obj/structure/flora/ash/cacti/Crossed(mob/AM)
|
||||
if(ishuman(AM) && has_gravity(loc) && prob(70))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(!H.shoes && !H.lying) //ouch, my feet.
|
||||
var/picked_def_zone = pick("l_leg", "r_leg")
|
||||
var/obj/item/organ/external/affected = H.get_organ(picked_def_zone)
|
||||
if(!istype(affected))
|
||||
return
|
||||
H.apply_damage(rand(3, 6), BRUTE, picked_def_zone)
|
||||
H.Weaken(2)
|
||||
H.visible_message("<span class='danger'>[H] steps on a cactus!</span>", \
|
||||
"<span class='userdanger'>You step on a cactus!</span>")
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora
|
||||
name = "mushroom shavings"
|
||||
desc = "Some shavings from a tall mushroom. With enough, might serve as a bowl."
|
||||
icon = 'icons/obj/lavaland/ash_flora.dmi'
|
||||
icon_state = "mushroom_shavings"
|
||||
list_reagents = list("sugar" = 3, "ethanol" = 2, "stabilizing_agent" = 3, "minttoxin" = 2)
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/New()
|
||||
..()
|
||||
pixel_x = rand(-4, 4)
|
||||
pixel_y = rand(-4, 4)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/shavings //for actual crafting
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_leaf
|
||||
name = "mushroom leaf"
|
||||
desc = "A leaf, from a mushroom."
|
||||
list_reagents = list("nutriment" = 3, "vitfro" = 2, "nicotine" = 2)
|
||||
icon_state = "mushroom_leaf"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_cap
|
||||
name = "mushroom cap"
|
||||
desc = "The cap of a large mushroom."
|
||||
list_reagents = list("lsd" = 2, "entpoly" = 4, "psilocybin" = 2)
|
||||
icon_state = "mushroom_cap"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_stem
|
||||
name = "mushroom stem"
|
||||
desc = "A long mushroom stem. It's slightly glowing."
|
||||
list_reagents = list("tinlux" = 2, "vitamin" = 1, "space_drugs" = 1)
|
||||
icon_state = "mushroom_stem"
|
||||
luminosity = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/cactus_fruit
|
||||
name = "cactus fruit"
|
||||
list_reagents = list("vitamin" = 2, "nutriment" = 2, "vitfro" = 4)
|
||||
desc = "A cactus fruit covered in a thick, reddish skin. And some ash."
|
||||
icon_state = "cactus_fruit"
|
||||
|
||||
/obj/item/mushroom_bowl
|
||||
name = "mushroom bowl"
|
||||
desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point."
|
||||
icon = 'icons/obj/lavaland/ash_flora.dmi'
|
||||
icon_state = "mushroom_bowl"
|
||||
w_class = 2
|
||||
|
||||
//what you can craft with these things
|
||||
/datum/crafting_recipe/mushroom_bowl
|
||||
name = "Mushroom Bowl"
|
||||
result = /obj/item/weapon/reagent_containers/food/drinks/mushroom_bowl
|
||||
reqs = list(/obj/item/weapon/reagent_containers/food/snacks/ash_flora/shavings = 5)
|
||||
time = 30
|
||||
category = CAT_PRIMAL
|
||||
@@ -0,0 +1,493 @@
|
||||
//Black Box
|
||||
|
||||
/obj/machinery/smartfridge/black_box
|
||||
name = "black box"
|
||||
desc = "A completely indestructible chunk of crystal, rumoured to predate the start of this universe. It looks like you could store things inside it."
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
icon_state = "blackbox"
|
||||
icon_on = "blackbox"
|
||||
icon_off = "blackbox"
|
||||
luminosity = 8
|
||||
max_n_of_items = INFINITY
|
||||
unacidable = 1
|
||||
pixel_y = -4
|
||||
use_power = 0
|
||||
var/memory_saved = FALSE
|
||||
var/list/stored_items = list()
|
||||
var/static/list/blacklist = typecacheof(list(/obj/item/weapon/spellbook))
|
||||
|
||||
/obj/machinery/smartfridge/black_box/update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/smartfridge/black_box/accept_check(obj/item/O)
|
||||
if(!istype(O))
|
||||
return FALSE
|
||||
if(is_type_in_typecache(O, blacklist))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/smartfridge/black_box/New()
|
||||
var/static/obj/machinery/smartfridge/black_box/current
|
||||
if(current && current != src)
|
||||
qdel(src, force=TRUE)
|
||||
return
|
||||
current = src
|
||||
ReadMemory()
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/smartfridge/black_box/process()
|
||||
..()
|
||||
if(!memory_saved && ticker.current_state == GAME_STATE_FINISHED)
|
||||
WriteMemory()
|
||||
|
||||
/obj/machinery/smartfridge/black_box/proc/WriteMemory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav")
|
||||
stored_items = list()
|
||||
|
||||
for(var/obj/O in (contents-component_parts))
|
||||
stored_items += O.type
|
||||
|
||||
S["stored_items"] << stored_items
|
||||
memory_saved = TRUE
|
||||
|
||||
/obj/machinery/smartfridge/black_box/proc/ReadMemory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav")
|
||||
S["stored_items"] >> stored_items
|
||||
|
||||
if(isnull(stored_items))
|
||||
stored_items = list()
|
||||
|
||||
for(var/item in stored_items)
|
||||
create_item(item)
|
||||
|
||||
//in it's own proc to avoid issues with items that nolonger exist in the code base.
|
||||
//try catch doesn't always prevent byond runtimes from halting a proc,
|
||||
/obj/machinery/smartfridge/black_box/proc/create_item(item_type)
|
||||
new item_type(src)
|
||||
|
||||
/obj/machinery/smartfridge/black_box/Destroy(force = FALSE)
|
||||
if(force)
|
||||
for(var/thing in src)
|
||||
qdel(thing)
|
||||
return ..()
|
||||
else
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
|
||||
//No taking it apart
|
||||
|
||||
/obj/machinery/smartfridge/black_box/default_deconstruction_screwdriver()
|
||||
return
|
||||
|
||||
/obj/machinery/smartfridge/black_box/exchange_parts()
|
||||
return
|
||||
|
||||
/obj/machinery/smartfridge/black_box/default_unfasten_wrench()
|
||||
return
|
||||
|
||||
/obj/machinery/smartfridge/black_box/default_deconstruction_crowbar()
|
||||
return
|
||||
|
||||
///Anomolous Crystal///
|
||||
|
||||
/obj/machinery/anomalous_crystal
|
||||
name = "anomalous crystal"
|
||||
desc = "A strange chunk of crystal, being in the presence of it fills you with equal parts excitement and dread."
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
icon_state = "anomaly_crystal"
|
||||
luminosity = 8
|
||||
use_power = 0
|
||||
density = 1
|
||||
unacidable = 1
|
||||
var/activation_method = "touch"
|
||||
var/activation_damage_type = null
|
||||
var/last_use_timer = 0
|
||||
var/cooldown_add = 30
|
||||
var/list/affected_targets = list()
|
||||
var/activation_sound = 'sound/effects/break_stone.ogg'
|
||||
|
||||
/obj/machinery/anomalous_crystal/New()
|
||||
activation_method = pick("touch","laser","bullet","energy","bomb","mob_bump","weapon","speech") // "heat" removed due to lack of is_hot()
|
||||
..()
|
||||
|
||||
/obj/machinery/anomalous_crystal/hear_talk(mob/speaker, message)
|
||||
..()
|
||||
if(isliving(speaker) && message)
|
||||
ActivationReaction(speaker, "speech")
|
||||
|
||||
/obj/machinery/anomalous_crystal/attack_hand(mob/user)
|
||||
..()
|
||||
ActivationReaction(user,"touch")
|
||||
|
||||
/obj/machinery/anomalous_crystal/attackby(obj/item/I, mob/user, params)
|
||||
ActivationReaction(user,"weapon")
|
||||
..()
|
||||
|
||||
/obj/machinery/anomalous_crystal/bullet_act(obj/item/projectile/P, def_zone)
|
||||
..()
|
||||
if(istype(P, /obj/item/projectile/magic))
|
||||
ActivationReaction(P.firer, "magic", P.damage_type)
|
||||
return
|
||||
ActivationReaction(P.firer, P.flag, P.damage_type)
|
||||
|
||||
/obj/machinery/anomalous_crystal/proc/ActivationReaction(mob/user, method, damtype)
|
||||
if(world.time < last_use_timer)
|
||||
return 0
|
||||
if(activation_damage_type && activation_damage_type != damtype)
|
||||
return 0
|
||||
if(method != activation_method)
|
||||
return 0
|
||||
last_use_timer = (world.time + cooldown_add)
|
||||
playsound(user, activation_sound, 100, 1)
|
||||
return 1
|
||||
|
||||
/obj/machinery/anomalous_crystal/Bumped(atom/AM as mob|obj)
|
||||
..()
|
||||
if(ismob(AM))
|
||||
ActivationReaction(AM,"mob_bump")
|
||||
|
||||
/obj/machinery/anomalous_crystal/ex_act()
|
||||
ActivationReaction(null,"bomb")
|
||||
|
||||
/obj/machinery/anomalous_crystal/random/New()//Just a random crysal spawner for loot
|
||||
var/random_crystal = pick(typesof(/obj/machinery/anomalous_crystal) - /obj/machinery/anomalous_crystal/random - /obj/machinery/anomalous_crystal)
|
||||
new random_crystal(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/anomalous_crystal/honk //Strips and equips you as a clown. I apologize for nothing
|
||||
activation_method = "mob_bump"
|
||||
activation_sound = 'sound/items/bikehorn.ogg'
|
||||
|
||||
/obj/machinery/anomalous_crystal/honk/ActivationReaction(mob/user)
|
||||
if(..() && ishuman(user) && !(user in affected_targets))
|
||||
var/mob/living/carbon/human/H = user
|
||||
for(var/obj/item/W in H)
|
||||
H.unEquip(W)
|
||||
var/datum/job/clown/C = job_master.GetJob("Clown")
|
||||
C.equip(H)
|
||||
affected_targets.Add(H)
|
||||
|
||||
/obj/machinery/anomalous_crystal/honk/New()
|
||||
..()
|
||||
activation_method = pick("mob_bump","speech")
|
||||
|
||||
/obj/machinery/anomalous_crystal/theme_warp //Warps the area you're in to look like a new one
|
||||
activation_method = "touch"
|
||||
cooldown_add = 200
|
||||
var/terrain_theme = "winter"
|
||||
var/NewTerrainFloors
|
||||
var/NewTerrainWalls
|
||||
var/NewTerrainChairs
|
||||
var/NewTerrainTables
|
||||
var/list/NewFlora = list()
|
||||
var/florachance = 8
|
||||
|
||||
/obj/machinery/anomalous_crystal/theme_warp/New()
|
||||
..()
|
||||
terrain_theme = pick("lavaland","winter","jungle","alien")
|
||||
switch(terrain_theme)
|
||||
if("lavaland")//Depressurizes the place... and free cult metal, I guess.
|
||||
NewTerrainFloors = /turf/simulated/floor/basalt // Needs to be updated after turf update
|
||||
NewTerrainWalls = /turf/simulated/wall/cult
|
||||
NewFlora = list(/mob/living/simple_animal/hostile/asteroid/goldgrub)
|
||||
florachance = 1
|
||||
if("winter") //Snow terrain is slow to move in and cold! Get the assistants to shovel your driveway.
|
||||
NewTerrainFloors = /turf/simulated/floor/snow // Needs to be updated after turf update
|
||||
NewTerrainWalls = /turf/simulated/wall/mineral/wood
|
||||
NewTerrainChairs = /obj/structure/stool/bed/chair/wood/normal
|
||||
NewTerrainTables = /obj/structure/table/glass
|
||||
NewFlora = list(/obj/structure/flora/grass/green, /obj/structure/flora/grass/brown, /obj/structure/flora/grass/both)
|
||||
if("jungle") //Beneficial due to actually having breathable air. Plus, monkeys and bows and arrows.
|
||||
NewTerrainFloors = /turf/simulated/floor/grass
|
||||
NewTerrainWalls = /turf/simulated/wall/mineral/sandstone
|
||||
NewTerrainChairs = /obj/structure/stool/bed/chair/wood/normal
|
||||
NewTerrainTables = /obj/structure/table/woodentable
|
||||
NewFlora = list(/obj/structure/flora/ausbushes/sparsegrass, /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/leafybush,
|
||||
/obj/structure/flora/ausbushes/grassybush, /obj/structure/flora/ausbushes/sunnybush, /obj/structure/flora/tree/palm, /mob/living/carbon/human/monkey,
|
||||
/obj/item/weapon/gun/projectile/bow, /obj/item/weapon/storage/backpack/quiver/full)
|
||||
florachance = 20
|
||||
if("alien") //Beneficial, turns stuff into alien alloy which is useful to cargo and research. Also repairs atmos.
|
||||
NewTerrainFloors = /turf/simulated/floor/mineral/abductor
|
||||
NewTerrainWalls = /turf/simulated/wall/mineral/abductor
|
||||
NewTerrainChairs = /obj/structure/stool/bed/abductor //ayys apparently don't have chairs. An entire species of people who only recline.
|
||||
NewTerrainTables = /obj/structure/table/abductor
|
||||
|
||||
/obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method)
|
||||
if(..())
|
||||
var/area/A = get_area(src)
|
||||
if(!A.outdoors && !(A in affected_targets))
|
||||
for(var/atom/Stuff in A)
|
||||
if(isturf(Stuff))
|
||||
var/turf/T = Stuff
|
||||
if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors)
|
||||
var/turf/simulated/O = T.ChangeTurf(NewTerrainFloors)
|
||||
if(O.air)
|
||||
var/datum/gas_mixture/G = O.air
|
||||
G.copy_from(O.air)
|
||||
if(prob(florachance) && NewFlora.len && !is_blocked_turf(O))
|
||||
var/atom/Picked = pick(NewFlora)
|
||||
new Picked(O)
|
||||
continue
|
||||
if(iswallturf(T) && NewTerrainWalls)
|
||||
T.ChangeTurf(NewTerrainWalls)
|
||||
continue
|
||||
if(istype(Stuff, /obj/structure/stool/bed/chair) && NewTerrainChairs)
|
||||
var/obj/structure/stool/bed/chair/Original = Stuff
|
||||
var/obj/structure/stool/bed/chair/C = new NewTerrainChairs(Original.loc)
|
||||
C.dir = Original.dir
|
||||
qdel(Stuff)
|
||||
continue
|
||||
if(istype(Stuff, /obj/structure/table) && NewTerrainTables)
|
||||
var/obj/structure/table/Original = Stuff
|
||||
var/obj/structure/table/T = new NewTerrainTables(Original.loc)
|
||||
T.dir = Original.dir
|
||||
qdel(Stuff)
|
||||
continue
|
||||
affected_targets += A
|
||||
|
||||
/obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with
|
||||
activation_method = "touch"
|
||||
cooldown_add = 50
|
||||
var/generated_projectile = /obj/item/projectile/beam/emitter
|
||||
|
||||
/obj/machinery/anomalous_crystal/emitter/New()
|
||||
..()
|
||||
generated_projectile = pick(/obj/item/projectile/magic/fireball/infernal,/obj/item/projectile/magic/spellblade,
|
||||
/obj/item/projectile/bullet/meteorshot, /obj/item/projectile/beam/xray, /obj/item/projectile/colossus)
|
||||
|
||||
/obj/machinery/anomalous_crystal/emitter/ActivationReaction(mob/user, method)
|
||||
if(..())
|
||||
var/obj/item/projectile/P = new generated_projectile(get_turf(src))
|
||||
P.dir = dir
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
P.yo = 20
|
||||
P.xo = 0
|
||||
if(EAST)
|
||||
P.yo = 0
|
||||
P.xo = 20
|
||||
if(WEST)
|
||||
P.yo = 0
|
||||
P.xo = -20
|
||||
else
|
||||
P.yo = -20
|
||||
P.xo = 0
|
||||
P.fire()
|
||||
|
||||
/obj/machinery/anomalous_crystal/dark_reprise //Revives anyone nearby, but turns them into shadowpeople and renders them uncloneable, so the crystal is your only hope of getting up again if you go down.
|
||||
activation_method = "touch"
|
||||
activation_sound = 'sound/hallucinations/growl1.ogg'
|
||||
|
||||
/obj/machinery/anomalous_crystal/dark_reprise/ActivationReaction(mob/user, method)
|
||||
if(..())
|
||||
for(var/i in range(1, src))
|
||||
if(isturf(i))
|
||||
new /obj/effect/overlay/temp/cult/sparks(i)
|
||||
continue
|
||||
if(ishuman(i))
|
||||
var/mob/living/carbon/human/H = i
|
||||
if(H.stat == DEAD)
|
||||
H.set_species("Shadow")
|
||||
H.revive()
|
||||
H.disabilities |= NOCLONE //Free revives, but significantly limits your options for reviving except via the crystal
|
||||
H.grab_ghost(force = TRUE)
|
||||
|
||||
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
|
||||
activation_method = "touch"
|
||||
var/ready_to_deploy = 0
|
||||
|
||||
/obj/machinery/anomalous_crystal/helpers/ActivationReaction(mob/user, method)
|
||||
if(..() && !ready_to_deploy)
|
||||
ready_to_deploy = 1
|
||||
notify_ghosts("An anomalous crystal has been activated in [get_area(src)]! This crystal can always be used by ghosts hereafter.", enter_link = "<a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
|
||||
|
||||
/obj/machinery/anomalous_crystal/helpers/attack_ghost(mob/dead/observer/user)
|
||||
..()
|
||||
if(ready_to_deploy)
|
||||
var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
|
||||
if(be_helper == "No")
|
||||
return
|
||||
var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc))
|
||||
W.key = user.key
|
||||
|
||||
/obj/machinery/anomalous_crystal/helpers/Topic(href, href_list)
|
||||
if(href_list["ghostjoin"])
|
||||
var/mob/dead/observer/ghost = usr
|
||||
if(istype(ghost))
|
||||
attack_ghost(ghost)
|
||||
|
||||
/mob/living/simple_animal/hostile/lightgeist
|
||||
name = "lightgeist"
|
||||
desc = "This small floating creature is a completely unknown form of life... being near it fills you with a sense of tranquility."
|
||||
icon_state = "lightgeist"
|
||||
icon_living = "lightgeist"
|
||||
icon_dead = "butterfly_dead"
|
||||
turns_per_move = 1
|
||||
response_help = "waves away"
|
||||
response_disarm = "brushes aside"
|
||||
response_harm = "disrupts"
|
||||
speak_emote = list("oscillates")
|
||||
maxHealth = 2
|
||||
health = 2
|
||||
harm_intent_damage = 1
|
||||
friendly = "mends"
|
||||
density = 0
|
||||
flying = 1
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
ventcrawler = 2
|
||||
mob_size = MOB_SIZE_TINY
|
||||
gold_core_spawnable = 0
|
||||
speak_emote = list("warps")
|
||||
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
luminosity = 4
|
||||
faction = list("neutral")
|
||||
universal_understand = 1
|
||||
del_on_death = 1
|
||||
unsuitable_atmos_damage = 0
|
||||
flying = 1
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 1500
|
||||
environment_smash = 0
|
||||
AIStatus = AI_OFF
|
||||
stop_automated_movement = 1
|
||||
var/heal_power = 5
|
||||
|
||||
/mob/living/simple_animal/hostile/lightgeist/New()
|
||||
..()
|
||||
verbs -= /mob/living/verb/pulled
|
||||
verbs -= /mob/verb/me_verb
|
||||
var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
medsensor.add_hud_to(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/lightgeist/AttackingTarget()
|
||||
..()
|
||||
if(isliving(target) && target != src)
|
||||
var/mob/living/L = target
|
||||
if(L.stat < DEAD)
|
||||
L.heal_overall_damage(heal_power, heal_power)
|
||||
new /obj/effect/overlay/temp/heal(get_turf(target), "#80F5FF")
|
||||
|
||||
/mob/living/simple_animal/hostile/lightgeist/ghostize()
|
||||
if(..())
|
||||
death()
|
||||
|
||||
/obj/machinery/anomalous_crystal/refresher //Deletes and recreates a copy of the item, "refreshing" it.
|
||||
activation_method = "touch"
|
||||
cooldown_add = 50
|
||||
activation_sound = 'sound/magic/TIMEPARADOX2.ogg'
|
||||
var/list/banned_items_typecache = list(/obj/item/weapon/storage, /obj/item/weapon/implant, /obj/item/weapon/implanter, /obj/item/weapon/disk/nuclear, /obj/item/projectile, /obj/item/weapon/spellbook)
|
||||
|
||||
/obj/machinery/anomalous_crystal/refresher/New()
|
||||
..()
|
||||
banned_items_typecache = typecacheof(banned_items_typecache)
|
||||
|
||||
|
||||
/obj/machinery/anomalous_crystal/refresher/ActivationReaction(mob/user, method)
|
||||
if(..())
|
||||
var/list/L = list()
|
||||
var/turf/T = get_step(src, dir)
|
||||
new /obj/effect/overlay/temp/emp/pulse(T)
|
||||
for(var/i in T)
|
||||
if(istype(i, /obj/item) && !is_type_in_typecache(i, banned_items_typecache))
|
||||
var/obj/item/W = i
|
||||
if(!W.admin_spawned)
|
||||
L += W
|
||||
if(L.len)
|
||||
var/obj/item/CHOSEN = pick(L)
|
||||
new CHOSEN.type(T)
|
||||
qdel(CHOSEN)
|
||||
|
||||
/obj/machinery/anomalous_crystal/possessor //Allows you to bodyjack small animals, then exit them at your leisure, but you can only do this once per activation. Because they blow up. Also, if the bodyjacked animal dies, SO DO YOU.
|
||||
activation_method = "touch"
|
||||
|
||||
/obj/machinery/anomalous_crystal/possessor/ActivationReaction(mob/user, method)
|
||||
if(..())
|
||||
if(ishuman(user))
|
||||
var/mobcheck = 0
|
||||
for(var/mob/living/simple_animal/A in range(1, src))
|
||||
if(A.melee_damage_upper > 5 || A.mob_size >= MOB_SIZE_LARGE || A.ckey || A.stat)
|
||||
break
|
||||
var/obj/structure/closet/stasis/S = new /obj/structure/closet/stasis(A)
|
||||
user.forceMove(S)
|
||||
mobcheck = 1
|
||||
break
|
||||
if(!mobcheck)
|
||||
new /mob/living/simple_animal/cockroach(get_step(src,dir)) //Just in case there aren't any animals on the station, this will leave you with a terrible option to possess if you feel like it
|
||||
|
||||
/obj/structure/closet/stasis
|
||||
name = "quantum entanglement stasis warp field"
|
||||
desc = "You can hardly comprehend this thing... which is why you can't see it."
|
||||
icon_state = null //This shouldn't even be visible, so if it DOES show up, at least nobody will notice
|
||||
density = 1
|
||||
anchored = 1
|
||||
var/mob/living/simple_animal/holder_animal
|
||||
|
||||
/obj/structure/closet/stasis/process()
|
||||
if(holder_animal)
|
||||
if(holder_animal.stat == DEAD && !qdeleted(holder_animal))
|
||||
dump_contents()
|
||||
holder_animal.gib()
|
||||
return
|
||||
|
||||
/obj/structure/closet/stasis/New()
|
||||
..()
|
||||
if(isanimal(loc))
|
||||
holder_animal = loc
|
||||
processing_objects.Add(src)
|
||||
|
||||
/obj/structure/closet/stasis/Entered(atom/A)
|
||||
if(isliving(A) && holder_animal)
|
||||
var/mob/living/L = A
|
||||
L.notransform = 1
|
||||
L.disabilities |= MUTE
|
||||
L.status_flags |= GODMODE
|
||||
L.mind.transfer_to(holder_animal)
|
||||
var/obj/effect/proc_holder/spell/targeted/exit_possession/P = new /obj/effect/proc_holder/spell/targeted/exit_possession
|
||||
holder_animal.mind.AddSpell(P)
|
||||
holder_animal.verbs -= /mob/living/verb/pulled
|
||||
|
||||
/obj/structure/closet/stasis/dump_contents(var/kill = 1)
|
||||
processing_objects.Remove(src)
|
||||
for(var/mob/living/L in src)
|
||||
L.disabilities &= ~MUTE
|
||||
L.status_flags &= ~GODMODE
|
||||
L.notransform = 0
|
||||
if(holder_animal && !qdeleted(holder_animal))
|
||||
holder_animal.mind.transfer_to(L)
|
||||
L.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
|
||||
if(kill || !isanimal(loc))
|
||||
L.death(0)
|
||||
..()
|
||||
|
||||
/obj/structure/closet/stasis/emp_act()
|
||||
return
|
||||
|
||||
/obj/structure/closet/stasis/ex_act()
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/exit_possession
|
||||
name = "Exit Possession"
|
||||
desc = "Exits the body you are possessing"
|
||||
charge_max = 60
|
||||
clothes_req = 0
|
||||
invocation_type = "none"
|
||||
max_targets = 1
|
||||
range = -1
|
||||
include_user = 1
|
||||
selection_type = "view"
|
||||
action_icon_state = "exit_possession"
|
||||
sound = null
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/exit_possession/cast(list/targets, mob/user = usr)
|
||||
if(!isfloorturf(user.loc))
|
||||
return
|
||||
var/datum/mind/target_mind = user.mind
|
||||
var/mob/living/current = user // Saving the current mob here to gib as usr seems to get confused after the mind's been transferred, due to delay in transfer_to
|
||||
for(var/i in user)
|
||||
if(istype(i, /obj/structure/closet/stasis))
|
||||
var/obj/structure/closet/stasis/S = i
|
||||
S.dump_contents(0)
|
||||
qdel(S)
|
||||
break
|
||||
current.gib()
|
||||
target_mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
|
||||
@@ -0,0 +1,618 @@
|
||||
//The chests dropped by mob spawner tendrils. Also contains associated loot.
|
||||
|
||||
/obj/structure/closet/crate/necropolis
|
||||
name = "necropolis chest"
|
||||
desc = "It's watching you closely."
|
||||
icon_state = "necrocrate"
|
||||
icon_opened = "necrocrateopen"
|
||||
icon_closed = "necrocrate"
|
||||
|
||||
/obj/structure/closet/crate/necropolis/tendril
|
||||
desc = "It's watching you suspiciously."
|
||||
|
||||
/obj/structure/closet/crate/necropolis/tendril/New()
|
||||
..()
|
||||
// uncomment me once these items are being implemented
|
||||
/*var/loot = rand(1,25)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/device/shared_storage/red(src)
|
||||
if(2)
|
||||
new /obj/item/clothing/suit/space/hardsuit/cult(src)
|
||||
if(3)
|
||||
new /obj/item/device/soulstone/anybody(src)
|
||||
if(4)
|
||||
new /obj/item/weapon/katana/cursed(src)
|
||||
if(5)
|
||||
new /obj/item/clothing/glasses/godeye(src)
|
||||
if(6)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/potion/flight(src)
|
||||
if(7)
|
||||
new /obj/item/weapon/pickaxe/diamond(src)
|
||||
if(8)
|
||||
new /obj/item/clothing/head/culthood(src)
|
||||
new /obj/item/clothing/suit/cultrobes(src)
|
||||
new /obj/item/weapon/bedsheet/cult(src)
|
||||
if(9)
|
||||
new /obj/item/organ/brain/alien(src)
|
||||
if(10)
|
||||
new /obj/item/organ/heart/cursed(src)
|
||||
if(11)
|
||||
new /obj/item/ship_in_a_bottle(src)
|
||||
if(12)
|
||||
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker(src)
|
||||
if(13)
|
||||
new /obj/item/weapon/sord(src)
|
||||
if(14)
|
||||
new /obj/item/weapon/nullrod/scythe/talking(src)
|
||||
if(15)
|
||||
new /obj/item/weapon/nullrod/armblade(src)
|
||||
if(16)
|
||||
new /obj/item/weapon/guardiancreator(src)
|
||||
if(17)
|
||||
new /obj/item/borg/upgrade/modkit/aoe/turfs/andmobs(src)
|
||||
if(18)
|
||||
new /obj/item/device/warp_cube/red(src)
|
||||
if(19)
|
||||
new /obj/item/device/wisp_lantern(src)
|
||||
if(20)
|
||||
new /obj/item/device/immortality_talisman(src)
|
||||
if(21)
|
||||
new /obj/item/weapon/gun/magic/hook(src)
|
||||
if(22)
|
||||
new /obj/item/voodoo(src)
|
||||
if(23)
|
||||
new /obj/item/weapon/grenade/clusterbuster/inferno(src)
|
||||
if(24)
|
||||
new /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater/hell(src)
|
||||
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src)
|
||||
if(25)
|
||||
new /obj/item/weapon/spellbook/oneuse/summonitem(src)*/
|
||||
|
||||
///Bosses
|
||||
|
||||
//Dragon
|
||||
|
||||
/obj/structure/closet/crate/necropolis/dragon
|
||||
name = "dragon chest"
|
||||
|
||||
/obj/structure/closet/crate/necropolis/dragon/New()
|
||||
..()
|
||||
var/loot = rand(1,4)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/weapon/melee/ghost_sword(src)
|
||||
if(2)
|
||||
new /obj/item/weapon/lava_staff(src)
|
||||
if(3)
|
||||
new /obj/item/weapon/spellbook/oneuse/sacredflame(src)
|
||||
new /obj/item/weapon/gun/magic/wand/fireball(src)
|
||||
if(4)
|
||||
new /obj/item/weapon/dragons_blood(src)
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword
|
||||
name = "spectral blade"
|
||||
desc = "A rusted and dulled blade. It doesn't look like it'd do much damage. It glows weakly."
|
||||
icon_state = "spectral"
|
||||
item_state = "spectral"
|
||||
flags = CONDUCT
|
||||
sharp = 1
|
||||
edge = 1
|
||||
w_class = 4
|
||||
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/weapon/melee/ghost_sword/New()
|
||||
..()
|
||||
spirits = list()
|
||||
processing_objects.Add(src)
|
||||
poi_list |= src
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/Destroy()
|
||||
for(var/mob/dead/observer/G in spirits)
|
||||
G.invisibility = initial(G.invisibility)
|
||||
spirits.Cut()
|
||||
processing_objects.Remove(src)
|
||||
poi_list -= src
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/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 their [src], calling for your help!", enter_link="<a href=?src=[UID()];follow=1>(Click to help)</a>", source = user, action = NOTIFY_FOLLOW)
|
||||
|
||||
summon_cooldown = world.time + 600
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/Topic(href, href_list)
|
||||
if(href_list["follow"])
|
||||
var/mob/dead/observer/ghost = usr
|
||||
if(istype(ghost))
|
||||
ghost.ManualFollow(src)
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/process()
|
||||
ghost_check()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/proc/ghost_check()
|
||||
var/ghost_counter = 0
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/contents = T.GetAllContents()
|
||||
var/mob/dead/observer/current_spirits = list()
|
||||
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
if(is_type_in_list(O.following, contents))
|
||||
ghost_counter++
|
||||
O.invisibility = 0
|
||||
current_spirits |= O
|
||||
|
||||
for(var/mob/dead/observer/G in spirits - current_spirits)
|
||||
G.invisibility = initial(G.invisibility)
|
||||
|
||||
spirits = current_spirits
|
||||
|
||||
return ghost_counter
|
||||
|
||||
/obj/item/weapon/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 class='danger'>[user] strikes with the force of [ghost_counter] vengeful spirits!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
|
||||
var/ghost_counter = ghost_check()
|
||||
final_block_chance += Clamp((ghost_counter * 5), 0, 75)
|
||||
owner.visible_message("<span class='danger'>[owner] is protected by a ring of [ghost_counter] ghosts!</span>")
|
||||
return ..()
|
||||
|
||||
// Blood
|
||||
|
||||
/obj/item/weapon/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/weapon/dragons_blood/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/random = rand(1,3)
|
||||
|
||||
switch(random)
|
||||
if(1)
|
||||
to_chat(user, "<span class='danger'>Your flesh begins to melt! Miraculously, you seem fine otherwise.</span>")
|
||||
H.set_species("Skeleton")
|
||||
if(2)
|
||||
to_chat(user, "<span class='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(3)
|
||||
to_chat(user, "<span class='danger'>You feel like you could walk straight through lava now.</span>")
|
||||
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("adminordrazine")
|
||||
agent = "dragon's blood"
|
||||
desc = "What do dragons have to do with Space Station 13?"
|
||||
stage_prob = 20
|
||||
severity = BIOHAZARD
|
||||
visibility_flags = 0
|
||||
stage1 = list("Your bones ache.")
|
||||
stage2 = list("Your skin feels scaley.")
|
||||
stage3 = list("<span class='danger'>You have an overwhelming urge to terrorize some peasants.</span>", "<span class='danger'>Your teeth feel sharper.</span>")
|
||||
stage4 = list("<span class='danger'>Your blood burns.</span>")
|
||||
stage5 = list("<span class='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.</span>")
|
||||
new_form = /mob/living/simple_animal/hostile/megafauna/dragon/lesser
|
||||
|
||||
//Lava Staff
|
||||
|
||||
/obj/item/weapon/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"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
item_state = "staffofstorms"
|
||||
w_class = 4
|
||||
force = 25
|
||||
damtype = BURN
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
var/turf_type = /turf/unsimulated/floor/lava // /turf/simulated/floor/plating/lava/smooth once Lavaland turfs are added
|
||||
var/transform_string = "lava"
|
||||
var/reset_turf_type = /turf/simulated/floor/plating/airless/asteroid // /turf/simulated/floor/plating/asteroid/basalt once Lavaland turfs are added
|
||||
var/reset_string = "basalt"
|
||||
var/create_cooldown = 100
|
||||
var/create_delay = 30
|
||||
var/reset_cooldown = 50
|
||||
var/timer = 0
|
||||
var/banned_turfs
|
||||
|
||||
/obj/item/weapon/lava_staff/New()
|
||||
. = ..()
|
||||
banned_turfs = typecacheof(list(/turf/space/transit, /turf/unsimulated))
|
||||
|
||||
/obj/item/weapon/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/simulated/T = get_turf(target)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(!istype(T, turf_type))
|
||||
var/obj/effect/overlay/temp/lavastaff/L = new /obj/effect/overlay/temp/lavastaff(T)
|
||||
L.alpha = 0
|
||||
animate(L, alpha = 255, time = create_delay)
|
||||
user.visible_message("<span class='danger'>[user] points [src] at [T]!</span>")
|
||||
timer = world.time + create_delay + 1
|
||||
if(do_after(user, create_delay, target = T))
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [transform_string]!</span>")
|
||||
message_admins("[key_name_admin(user)] fired the lava staff at [get_area(target)] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>).")
|
||||
log_game("[key_name(user)] fired the lava staff at [get_area(target)] ([T.x], [T.y], [T.z]).")
|
||||
T.ChangeTurf(turf_type)
|
||||
timer = world.time + create_cooldown
|
||||
qdel(L)
|
||||
else
|
||||
timer = world.time
|
||||
qdel(L)
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [reset_string]!</span>")
|
||||
T.ChangeTurf(reset_turf_type)
|
||||
timer = world.time + reset_cooldown
|
||||
playsound(T,'sound/magic/Fireball.ogg', 200, 1)
|
||||
|
||||
/obj/effect/overlay/temp/lavastaff
|
||||
icon_state = "lavastaff_warn"
|
||||
duration = 50
|
||||
|
||||
// Bubblegum
|
||||
|
||||
/obj/structure/closet/crate/necropolis/bubblegum
|
||||
name = "bubblegum chest"
|
||||
|
||||
/obj/structure/closet/crate/necropolis/bubblegum/New()
|
||||
..()
|
||||
var/loot = rand(1,3)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/mayhem(src)
|
||||
if(2)
|
||||
new /obj/item/blood_contract(src)
|
||||
if(3)
|
||||
new /obj/item/weapon/gun/magic/staff/spellblade(src)
|
||||
|
||||
// Mayhem
|
||||
|
||||
/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))
|
||||
spawn()
|
||||
var/obj/effect/mine/pickup/bloodbath/B = new(H)
|
||||
B.mineEffect(H)
|
||||
to_chat(user, "<span class='notice'>You shatter the bottle!</span>")
|
||||
playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1)
|
||||
qdel(src)
|
||||
|
||||
// Blood Contract
|
||||
|
||||
/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/choice = input(user,"Who do you want dead?","Choose Your Victim") as null|anything in player_list
|
||||
|
||||
if(!choice)
|
||||
used = FALSE
|
||||
return
|
||||
else if(!isliving(choice))
|
||||
to_chat(user, "[choice] is already dead!")
|
||||
used = FALSE
|
||||
return
|
||||
else
|
||||
var/mob/living/L = choice
|
||||
|
||||
message_admins("[key_name_admin(L)] has been marked for death by [key_name_admin(user)].")
|
||||
log_admin("[key_name(L)] has been marked for death by [key_name(user)].")
|
||||
|
||||
var/datum/objective/survive/survive = new
|
||||
survive.owner = L.mind
|
||||
L.mind.objectives += survive
|
||||
to_chat(L, "<span class='userdanger'>You've been marked for death! Don't let the demons get you!</span>")
|
||||
L.color = "#FF0000"
|
||||
spawn()
|
||||
var/obj/effect/mine/pickup/bloodbath/B = new(L)
|
||||
B.mineEffect(L)
|
||||
|
||||
for(var/mob/living/carbon/human/H in player_list)
|
||||
if(H == L)
|
||||
continue
|
||||
to_chat(H, "<span class='userdanger'>You have an overwhelming desire to kill [L]. They have been marked red! Go kill them!</span>")
|
||||
H.put_in_hands(new /obj/item/weapon/kitchen/knife/butcher(H))
|
||||
|
||||
qdel(src)
|
||||
|
||||
// Legion
|
||||
|
||||
// Staff of Storms
|
||||
|
||||
/obj/item/weapon/staff/storm
|
||||
name = "staff of storms"
|
||||
desc = "An ancient staff retrieved from the remains of Legion. The wind stirs as you move it."
|
||||
icon_state = "staffofstorms"
|
||||
item_state = "staffofstorms"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
item_state = "staffofstorms"
|
||||
w_class = 4
|
||||
force = 25
|
||||
damtype = BURN
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
var/storm_type = /datum/weather/ash_storm
|
||||
var/storm_cooldown = 0
|
||||
|
||||
/obj/item/weapon/staff/storm/attack_self(mob/user)
|
||||
if(storm_cooldown > world.time)
|
||||
to_chat(user, "<span class='warning'>The staff is still recharging!</span>")
|
||||
return
|
||||
|
||||
var/area/user_area = get_area(user)
|
||||
var/datum/weather/A
|
||||
var/z_level_name = space_manager.levels_by_name[user.z]
|
||||
for(var/V in weather_master.existing_weather)
|
||||
var/datum/weather/W = V
|
||||
if(W.target_z == z_level_name && W.area_type == user_area.type)
|
||||
A = W
|
||||
break
|
||||
if(A)
|
||||
|
||||
if(A.stage != END_STAGE)
|
||||
if(A.stage == WIND_DOWN_STAGE)
|
||||
to_chat(user, "<span class='warning'>The storm is already ending! It would be a waste to use the staff now.</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] holds [src] skywards as an orange beam travels into the sky!</span>", \
|
||||
"<span class='notice'>You hold [src] skyward, dispelling the storm!</span>")
|
||||
playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
|
||||
A.wind_down()
|
||||
return
|
||||
else
|
||||
A = new storm_type
|
||||
A.name = "staff storm"
|
||||
A.area_type = user_area.type
|
||||
A.target_z = z_level_name
|
||||
A.telegraph_duration = 100
|
||||
A.end_duration = 100
|
||||
|
||||
user.visible_message("<span class='warning'>[user] holds [src] skywards as red lightning crackles into the sky!</span>", \
|
||||
"<span class='notice'>You hold [src] skyward, calling down a terrible storm!</span>")
|
||||
playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
|
||||
A.telegraph()
|
||||
storm_cooldown = world.time + 200
|
||||
|
||||
// Hierophant
|
||||
|
||||
//Hierophant
|
||||
|
||||
/obj/item/weapon/hierophant_staff
|
||||
name = "Hierophant's staff"
|
||||
desc = "A large club with intense magic power infused into it."
|
||||
icon_state = "hierophant_staff"
|
||||
item_state = "hierophant_staff"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = 4
|
||||
force = 20
|
||||
hitsound = "swing_hit"
|
||||
//hitsound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire)
|
||||
var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is
|
||||
var/chaser_cooldown = 101 //how long the cooldown between firing chasers at mobs is
|
||||
var/chaser_timer = 0 //what our current chaser cooldown is
|
||||
var/timer = 0 //what our current cooldown is
|
||||
var/blast_range = 3 //how long the cardinal blast's walls are
|
||||
var/obj/effect/hierophant/rune //the associated rune 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/weapon/hierophant_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
..()
|
||||
var/turf/T = get_turf(target)
|
||||
if(!T || timer > world.time)
|
||||
return
|
||||
timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown
|
||||
if(proximity_flag)
|
||||
spawn(0)
|
||||
aoe_burst(T, user)
|
||||
add_logs(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)
|
||||
spawn(0)
|
||||
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
|
||||
new /obj/effect/overlay/temp/hierophant/chaser(get_turf(user), user, target, 1.5, friendly_fire_check)
|
||||
add_logs(user, target, "fired a chaser at", src)
|
||||
else
|
||||
spawn(0)
|
||||
cardinal_blasts(T, user) //otherwise, just do cardinal blast
|
||||
add_logs(user, target, "fired cardinal blast at", src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>That target is out of range!</span>") //too far away
|
||||
|
||||
/obj/item/weapon/hierophant_staff/ui_action_click(mob/user, actiontype)
|
||||
if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire...
|
||||
friendly_fire_check = !friendly_fire_check
|
||||
to_chat(user, "<span class='warning'>You toggle friendly fire [friendly_fire_check ? "off":"on"]!</span>")
|
||||
return
|
||||
if(user.get_active_hand() != src && user.get_inactive_hand() != src) //you need to hold the staff to teleport
|
||||
to_chat(user, "<span class='warning'>You need to hold the staff in your hands to [rune ? "teleport with it" : "create a rune"]!</span>")
|
||||
return
|
||||
if(!rune)
|
||||
if(isturf(user.loc))
|
||||
user.visible_message("<span class='hierophant_warning'>[user] holds [src] carefully in front of them, moving it in a strange pattern...</span>", \
|
||||
"<span class='notice'>You start creating a hierophant rune to teleport to...</span>")
|
||||
timer = world.time + 51
|
||||
if(do_after(user, 50, target = user))
|
||||
var/turf/T = get_turf(user)
|
||||
playsound(T,'sound/magic/Blind.ogg', 200, 1, -4)
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/teleport(T, user)
|
||||
var/obj/effect/hierophant/H = new/obj/effect/hierophant(T)
|
||||
rune = H
|
||||
user.update_action_buttons_icon()
|
||||
user.visible_message("<span class='hierophant_warning'>[user] creates a strange rune beneath them!</span>", \
|
||||
"<span class='hierophant'>You create a hierophant rune, which you can teleport yourself and any allies to at any time!</span>\n\
|
||||
<span class='notice'>You can remove the rune to place a new one by striking it with the staff.</span>")
|
||||
else
|
||||
timer = world.time
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to be on solid ground to produce a rune!</span>")
|
||||
return
|
||||
if(get_dist(user, rune) <= 2) //rune too close abort
|
||||
to_chat(user, "<span class='warning'>You are too close to the rune to teleport to it!</span>")
|
||||
return
|
||||
if(is_blocked_turf(get_turf(rune)))
|
||||
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
|
||||
return
|
||||
teleporting = TRUE //start channel
|
||||
user.update_action_buttons_icon()
|
||||
user.visible_message("<span class='hierophant_warning'>[user] starts to glow faintly...</span>")
|
||||
timer = world.time + 50
|
||||
if(do_after(user, 40, target = user) && rune)
|
||||
var/turf/T = get_turf(rune)
|
||||
var/turf/source = get_turf(user)
|
||||
if(is_blocked_turf(T))
|
||||
teleporting = FALSE
|
||||
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph(T, user)
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph(source, user)
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
|
||||
playsound(source,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
|
||||
if(!do_after(user, 3, target = user) || !rune) //no walking away shitlord
|
||||
teleporting = FALSE
|
||||
if(user)
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
if(is_blocked_turf(T))
|
||||
teleporting = FALSE
|
||||
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
add_logs(user, rune, "teleported self from ([source.x],[source.y],[source.z]) to")
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/teleport(T, user)
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/teleport(source, user)
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
var/obj/effect/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/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/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/hierophant/blast(t, user, TRUE) //but absolutely will hurt enemies
|
||||
B.damage = 30
|
||||
for(var/mob/living/L in range(1, source))
|
||||
spawn(0)
|
||||
teleport_mob(source, L, T, user) //regardless, take all mobs near us along
|
||||
sleep(6) //at this point the blasts detonate
|
||||
else
|
||||
timer = world.time
|
||||
teleporting = FALSE
|
||||
if(user)
|
||||
user.update_action_buttons_icon()
|
||||
|
||||
/obj/item/weapon/hierophant_staff/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))
|
||||
return
|
||||
animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
M.visible_message("<span class='hierophant_warning'>[M] fades out!</span>")
|
||||
sleep(2)
|
||||
if(!M)
|
||||
return
|
||||
M.forceMove(turf_to_teleport_to)
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
animate(M, alpha = 255, time = 2, easing = EASE_IN) //fade IN
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
M.visible_message("<span class='hierophant_warning'>[M] fades in!</span>")
|
||||
if(user != M)
|
||||
add_logs(user, M, "teleported", null, "from ([source.x],[source.y],[source.z])")
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
|
||||
if(!T)
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/cardinal(T, user)
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
new /obj/effect/overlay/temp/hierophant/blast(T, user, friendly_fire_check)
|
||||
for(var/d in cardinal)
|
||||
spawn(0)
|
||||
blast_wall(T, d, user)
|
||||
|
||||
/obj/item/weapon/hierophant_staff/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
|
||||
new /obj/effect/overlay/temp/hierophant/blast(J, user, friendly_fire_check)
|
||||
previousturf = J
|
||||
J = get_step(previousturf, dir)
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target
|
||||
if(!T)
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph(T, user)
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
new /obj/effect/overlay/temp/hierophant/blast(t, user, friendly_fire_check)
|
||||
@@ -13,6 +13,7 @@
|
||||
power_environ = 0
|
||||
power_equip = 0
|
||||
power_light = 0
|
||||
outdoors = 1
|
||||
ambientsounds = list('sound/ambience/ambimine.ogg')
|
||||
|
||||
/area/mine/dangerous/unexplored
|
||||
@@ -25,6 +26,7 @@
|
||||
power_environ = 0
|
||||
power_equip = 0
|
||||
power_light = 0
|
||||
outdoors = 1
|
||||
ambientsounds = list('sound/ambience/ambimine.ogg')
|
||||
|
||||
/area/mine/lobby
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
//this item is intended to give the effect of entering the mine, so that light gradually fades
|
||||
/obj/effect/light_emitter
|
||||
name = "Light-emtter"
|
||||
name = "Light emtter"
|
||||
anchored = 1
|
||||
invisibility = 101
|
||||
unacidable = 1
|
||||
light_range = 8
|
||||
light_power = 0
|
||||
|
||||
/**********************Miner Lockers**************************/
|
||||
|
||||
@@ -89,7 +91,7 @@
|
||||
var/excavation_amount = 100
|
||||
|
||||
/obj/item/weapon/pickaxe/proc/playDigSound()
|
||||
playsound(src, pick(digsound),20,1)
|
||||
playsound(src, pick(digsound),20,1)
|
||||
|
||||
/obj/item/weapon/pickaxe/silver
|
||||
name = "silver-plated pickaxe"
|
||||
|
||||
@@ -62,6 +62,10 @@
|
||||
points = 1
|
||||
refined_type = /obj/item/stack/sheet/glass
|
||||
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/weapon/ore/glass/basalt
|
||||
name = "volcanic ash"
|
||||
icon_state = "volcanic_sand"
|
||||
|
||||
/obj/item/weapon/ore/glass/attack_self(mob/living/user as mob)
|
||||
to_chat(user, "<span class='notice'>You use the sand to make sandstone.</span>")
|
||||
|
||||
Reference in New Issue
Block a user