Port over remaining Lavaland ruins

This commit is contained in:
Mark van Alphen
2019-06-07 01:19:55 +02:00
parent 10ef2311ab
commit ba3f65049d
89 changed files with 10091 additions and 275 deletions
@@ -0,0 +1,244 @@
// Dead Ratvar
/obj/structure/dead_ratvar
name = "hulking wreck"
desc = "The remains of a monstrous war machine."
icon = 'icons/obj/lavaland/dead_ratvar.dmi'
icon_state = "dead_ratvar"
flags = ON_BORDER
appearance_flags = 0
layer = FLY_LAYER
anchored = TRUE
density = TRUE
bound_width = 416
bound_height = 64
pixel_y = -10
unacidable = TRUE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF
// An "overlay" used by clockwork walls and floors to appear normal to mesons.
/obj/effect/clockwork/overlay
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/atom/linked
/obj/effect/clockwork/overlay/examine(mob/user)
if(linked)
linked.examine(user)
/obj/effect/clockwork/overlay/ex_act()
return FALSE
/obj/effect/clockwork/overlay/singularity_act()
return
/obj/effect/clockwork/overlay/singularity_pull()
return
/obj/effect/clockwork/overlay/singularity_pull(S, current_size)
return
/obj/effect/clockwork/overlay/Destroy()
if(linked)
linked = null
. = ..()
/obj/effect/clockwork/overlay/wall
name = "clockwork wall"
icon = 'icons/turf/walls/clockwork_wall.dmi'
icon_state = "clockwork_wall"
canSmoothWith = list(/obj/effect/clockwork/overlay/wall, /obj/structure/falsewall/brass)
smooth = SMOOTH_TRUE
layer = CLOSED_TURF_LAYER
/obj/effect/clockwork/overlay/wall/Initialize(mapload)
. = ..()
queue_smooth_neighbors(src)
addtimer(CALLBACK(GLOBAL_PROC, .proc/queue_smooth, src), 1)
/obj/effect/clockwork/overlay/wall/Destroy()
queue_smooth_neighbors(src)
return ..()
/obj/effect/clockwork/overlay/floor
icon = 'icons/turf/floors.dmi'
icon_state = "clockwork_floor"
layer = TURF_LAYER
plane = FLOOR_PLANE
/obj/effect/clockwork/overlay/floor/bloodcult //this is used by BLOOD CULT, it shouldn't use such a path...
icon_state = "cult"
// Wall gears
//A massive gear, effectively a girder for clocks.
/obj/structure/clockwork/wall_gear
name = "massive gear"
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "wall_gear"
climbable = TRUE
max_integrity = 100
can_deconstruct = TRUE
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
/obj/structure/clockwork/wall_gear/displaced
anchored = FALSE
/obj/structure/clockwork/wall_gear/Initialize()
. = ..()
new /obj/effect/temp_visual/ratvar/gear(get_turf(src))
/obj/structure/clockwork/wall_gear/emp_act(severity)
return
/obj/structure/clockwork/wall_gear/attackby(obj/item/I, mob/user, params)
if(iswrench(I))
default_unfasten_wrench(user, I, 10)
return 1
else if(isscrewdriver(I))
if(anchored)
to_chat(user, "<span class='warning'>[src] needs to be unsecured to disassemble it!</span>")
else
var/obj/item/screwdriver/S = I
user.visible_message("<span class='warning'>[user] starts to disassemble [src].</span>", "<span class='notice'>You start to disassemble [src]...</span>")
if(do_after(user, 30 * S.toolspeed, target = src) && !anchored)
playsound(loc, S.usesound, 50, 1)
to_chat(user, "<span class='notice'>You disassemble [src].</span>")
deconstruct(TRUE)
return 1
else if(istype(I, /obj/item/stack/tile/brass))
var/obj/item/stack/tile/brass/W = I
if(W.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one brass sheet to do this!</span>")
return
var/turf/T = get_turf(src)
if(iswallturf(T))
to_chat(user, "<span class='warning'>There is already a wall present!</span>")
return
if(!isfloorturf(T))
to_chat(user, "<span class='warning'>A floor must be present to build a [anchored ? "false ":""]wall!</span>")
return
if(locate(/obj/structure/falsewall) in T.contents)
to_chat(user, "<span class='warning'>There is already a false wall present!</span>")
return
to_chat(user, "<span class='notice'>You start adding [W] to [src]...</span>")
if(do_after(user, 20, target = src))
var/brass_floor = FALSE
if(istype(T, /turf/simulated/floor/clockwork)) //if the floor is already brass, costs less to make(conservation of masssssss)
brass_floor = TRUE
if(W.use(2 - brass_floor))
if(anchored)
T.ChangeTurf(/turf/simulated/wall/clockwork)
else
T.ChangeTurf(/turf/simulated/floor/clockwork)
new /obj/structure/falsewall/brass(T)
qdel(src)
else
to_chat(user, "<span class='warning'>You need more brass to make a [anchored ? "false ":""]wall!</span>")
return 1
return ..()
/obj/structure/clockwork/wall_gear/deconstruct(disassembled = TRUE)
if(can_deconstruct && disassembled)
new /obj/item/stack/tile/brass(loc, 3)
return ..()
//Shards of Alloy, suitable only as a source of power for a replica fabricator.
/obj/item/clockwork/alloy_shards
name = "replicant alloy shards"
desc = "Broken shards of some oddly malleable metal. They occasionally move and seem to glow."
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "alloy_shards"
resistance_flags = LAVA_PROOF | FIRE_PROOF
unacidable = TRUE
var/randomsinglesprite = FALSE
var/randomspritemax = 2
var/sprite_shift = 9
/obj/item/clockwork/alloy_shards/Initialize()
. = ..()
if(randomsinglesprite)
replace_name_desc()
icon_state = "[icon_state][rand(1, randomspritemax)]"
pixel_x = rand(-sprite_shift, sprite_shift)
pixel_y = rand(-sprite_shift, sprite_shift)
/obj/item/clockwork/alloy_shards/proc/replace_name_desc()
name = "replicant alloy shard"
desc = "A broken shard of some oddly malleable metal. It occasionally moves and seems to glow."
/obj/item/clockwork/alloy_shards/clockgolem_remains
name = "clockwork golem scrap"
desc = "A pile of scrap metal. It seems damaged beyond repair."
icon_state = "clockgolem_dead"
sprite_shift = 0
/obj/item/clockwork/alloy_shards/large
w_class = WEIGHT_CLASS_TINY
randomsinglesprite = TRUE
icon_state = "shard_large"
sprite_shift = 9
/obj/item/clockwork/alloy_shards/medium
w_class = WEIGHT_CLASS_TINY
randomsinglesprite = TRUE
icon_state = "shard_medium"
sprite_shift = 10
/obj/item/clockwork/alloy_shards/medium/gear_bit
randomspritemax = 4
icon_state = "gear_bit"
sprite_shift = 12
/obj/item/clockwork/alloy_shards/medium/gear_bit/replace_name_desc()
name = "gear bit"
desc = "A broken chunk of a gear. You want it."
/obj/item/clockwork/alloy_shards/medium/gear_bit/large //gives more power
/obj/item/clockwork/alloy_shards/medium/gear_bit/large/replace_name_desc()
..()
name = "complex gear bit"
/obj/item/clockwork/alloy_shards/small
w_class = WEIGHT_CLASS_TINY
randomsinglesprite = TRUE
randomspritemax = 3
icon_state = "shard_small"
sprite_shift = 12
/obj/item/clockwork/alloy_shards/pinion_lock
name = "pinion lock"
desc = "A dented and scratched gear. It's very heavy."
icon_state = "pinion_lock"
/obj/item/clockwork/component/belligerent_eye
name = "belligerent eye"
desc = "A brass construct with a rotating red center. It's as though it's looking for something to hurt."
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "belligerent_eye"
/obj/item/clockwork/component/belligerent_eye/blind_eye
name = "blind eye"
desc = "A heavy brass eye, its red iris fallen dark."
icon_state = "blind_eye"
w_class = WEIGHT_CLASS_NORMAL
/obj/item/clockwork/component/geis_capacitor/fallen_armor
name = "fallen armor"
desc = "Lifeless chunks of armor. They're designed in a strange way and won't fit on you."
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "fallen_armor"
w_class = WEIGHT_CLASS_NORMAL
//Ratvarian spear: A relatively fragile spear from the Celestial Derelict. Deals extreme damage to silicons and enemy cultists, but doesn't last long when summoned.
/obj/item/clockwork/weapon/ratvarian_spear
name = "ratvarian spear"
desc = "A razor-sharp spear made of brass. It thrums with barely-contained energy."
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "ratvarian_spear"
item_state = "ratvarian_spear"
force = 15 //Extra damage is dealt to targets in attack()
throwforce = 25
armour_penetration = 10
sharp = TRUE
attack_verb = list("stabbed", "poked", "slashed")
hitsound = 'sound/weapons/bladeslice.ogg'
w_class = WEIGHT_CLASS_BULKY
var/bonus_burn = 5
@@ -0,0 +1,49 @@
/obj/structure/sacrificealtar
name = "sacrificial altar"
desc = "An altar designed to perform blood sacrifice for a deity."
icon = 'icons/obj/hand_of_god_structures.dmi'
icon_state = "sacrificealtar"
anchored = TRUE
density = FALSE
can_buckle = TRUE
/obj/structure/sacrificealtar/attack_hand(mob/living/user)
if(user.incapacitated())
return
if(!has_buckled_mobs())
return
var/mob/living/L = buckled_mob
if(!L)
return
to_chat(user, "<span class='notice'>You attempt to sacrifice [L] by invoking the sacrificial ritual.</span>")
L.gib()
message_admins("[ADMIN_LOOKUPFLW(user)] has sacrificed [key_name_admin(L)] on the sacrificial altar at [AREACOORD(src)].")
/obj/structure/healingfountain
name = "healing fountain"
desc = "A fountain containing the waters of life."
icon = 'icons/obj/hand_of_god_structures.dmi'
icon_state = "fountain"
anchored = TRUE
density = TRUE
var/time_between_uses = 1800
var/last_process = 0
/obj/structure/healingfountain/attack_hand(mob/living/user)
. = ..()
if(.)
return
if(last_process + time_between_uses > world.time)
to_chat(user, "<span class='notice'>The fountain appears to be empty.</span>")
return
last_process = world.time
to_chat(user, "<span class='notice'>The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards.</span>")
user.reagents.add_reagent(/datum/reagent/medicine/omnizine/godblood, 20)
update_icon()
addtimer(CALLBACK(src, .proc/update_icon), time_between_uses)
/obj/structure/healingfountain/update_icon()
if(last_process + time_between_uses > world.time)
icon_state = "fountain"
else
icon_state = "fountain-red"
@@ -0,0 +1,7 @@
/obj/effect/spawner/lootdrop/pizzaparty
name = "pizza bomb spawner"
loot = list(/obj/item/pizzabox/margherita = 3,
/obj/item/pizzabox/meat = 3,
/obj/item/pizzabox/mushroom = 3,
/obj/item/pizza_bomb = 1)
lootdoubles = FALSE
@@ -0,0 +1,351 @@
/obj/effect/sliding_puzzle
name = "Sliding puzzle generator"
icon = 'icons/obj/items.dmi' //mapping
icon_state = "syndballoon"
invisibility = INVISIBILITY_ABSTRACT
anchored = TRUE
var/list/elements
var/floor_type = /turf/simulated/floor/vault
var/finished = FALSE
var/reward_type = /obj/item/reagent_containers/food/snacks/cookie
var/element_type = /obj/structure/puzzle_element
var/auto_setup = TRUE
var/empty_tile_id
//Gets the turf where the tile with given id should be
/obj/effect/sliding_puzzle/proc/get_turf_for_id(id)
var/turf/center = get_turf(src)
switch(id)
if(1)
return get_step(center,NORTHWEST)
if(2)
return get_step(center,NORTH)
if(3)
return get_step(center,NORTHEAST)
if(4)
return get_step(center,WEST)
if(5)
return center
if(6)
return get_step(center,EAST)
if(7)
return get_step(center,SOUTHWEST)
if(8)
return get_step(center,SOUTH)
if(9)
return get_step(center,SOUTHEAST)
/obj/effect/sliding_puzzle/Initialize(mapload)
..()
return INITIALIZE_HINT_LATELOAD
/obj/effect/sliding_puzzle/LateInitialize()
if(auto_setup)
setup()
/obj/effect/sliding_puzzle/proc/check_setup_location()
for(var/id in 1 to 9)
var/turf/T = get_turf_for_id(id)
if(!T)
return FALSE
if(istype(T, /turf/simulated/wall/indestructible) || istype(T, /turf/simulated/floor/indestructible))
return FALSE
return TRUE
/obj/effect/sliding_puzzle/proc/validate()
if(finished)
return
if(elements.len < 8) //Someone broke it
qdel(src)
//Check if everything is in place
for(var/id in 1 to 9)
var/target_turf = get_turf_for_id(id)
var/obj/structure/puzzle_element/E = locate() in target_turf
if(id == empty_tile_id && !E) // This location should be empty.
continue
if(!E || E.id != id) //wrong tile or no tile at all
return
//Ding ding
finish()
/obj/effect/sliding_puzzle/Destroy()
if(LAZYLEN(elements))
for(var/obj/structure/puzzle_element/E in elements)
E.source = null
elements.Cut()
return ..()
#define COLLAPSE_DURATION 7
/obj/effect/sliding_puzzle/proc/finish()
finished = TRUE
for(var/mob/M in range(7,src))
shake_camera(M, COLLAPSE_DURATION , 1)
for(var/obj/structure/puzzle_element/E in elements)
E.collapse()
dispense_reward()
/obj/effect/sliding_puzzle/proc/dispense_reward()
new reward_type(get_turf(src))
/obj/effect/sliding_puzzle/proc/is_solvable()
var/list/current_ordering = list()
for(var/obj/structure/puzzle_element/E in elements_in_order())
current_ordering += E.id
var/swap_tally = 0
for(var/i in 1 to current_ordering.len)
var/checked_value = current_ordering[i]
for(var/j in i to current_ordering.len)
if(current_ordering[j] < checked_value)
swap_tally++
return swap_tally % 2 == 0
//swap two tiles in same row
/obj/effect/sliding_puzzle/proc/make_solvable()
var/first_tile_id = 1
var/other_tile_id = 2
if(empty_tile_id == 1 || empty_tile_id == 2) //Can't swap with empty one so just grab some in second row
first_tile_id = 4
other_tile_id = 5
var/turf/T1 = get_turf_for_id(first_tile_id)
var/turf/T2 = get_turf_for_id(other_tile_id)
var/obj/structure/puzzle_element/E1 = locate() in T1
var/obj/structure/puzzle_element/E2 = locate() in T2
E1.forceMove(T2)
E2.forceMove(T1)
/proc/cmp_xy_desc(atom/movable/A, atom/movable/B)
if(A.y > B.y)
return -1
if(A.y < B.y)
return 1
if(A.x > B.x)
return 1
if(A.x < B.x)
return -1
return 0
/obj/effect/sliding_puzzle/proc/elements_in_order()
return sortTim(elements,cmp=/proc/cmp_xy_desc)
/obj/effect/sliding_puzzle/proc/get_base_icon()
var/icon/I = new('icons/obj/puzzle.dmi')
var/list/puzzles = icon_states(I)
var/puzzle_state = pick(puzzles)
var/icon/P = new('icons/obj/puzzle.dmi',puzzle_state)
return P
/obj/effect/sliding_puzzle/proc/setup()
//First we slice the 96x96 icon into 32x32 pieces
var/list/puzzle_pieces = list() //id -> icon list
var/width = 3
var/height = 3
var/list/left_ids = list()
var/tile_count = width * height
//Generate per tile icons
for(var/id in 1 to tile_count)
var/y = width - round((id - 1) / width)
var/x = ((id - 1) % width) + 1
var/x_start = 1 + (x - 1) * world.icon_size
var/x_end = x_start + world.icon_size - 1
var/y_start = 1 + ((y - 1) * world.icon_size)
var/y_end = y_start + world.icon_size - 1
var/icon/T = get_base_icon()
T.Crop(x_start,y_start,x_end,y_end)
puzzle_pieces["[id]"] = T
left_ids += id
//Setup random empty tile
empty_tile_id = pick_n_take(left_ids)
var/turf/empty_tile_turf = get_turf_for_id(empty_tile_id)
empty_tile_turf.ChangeTurf(floor_type, keep_icon = FALSE, ignore_air = FALSE)
var/mutable_appearance/MA = new(puzzle_pieces["[empty_tile_id]"])
MA.layer = empty_tile_turf.layer + 0.1
empty_tile_turf.add_overlay(MA)
elements = list()
var/list/empty_spots = left_ids.Copy()
for(var/spot_id in empty_spots)
var/turf/T = get_turf_for_id(spot_id)
T = T.ChangeTurf(floor_type, keep_icon = FALSE, ignore_air = FALSE)
var/obj/structure/puzzle_element/E = new element_type(T)
elements += E
var/chosen_id = pick_n_take(left_ids)
E.puzzle_icon = puzzle_pieces["[chosen_id]"]
E.source = src
E.id = chosen_id
E.set_puzzle_icon()
if(!is_solvable())
make_solvable()
/obj/structure/puzzle_element
name = "mysterious pillar"
desc = "puzzling..."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "puzzle_pillar"
anchored = FALSE
density = TRUE
var/id = 0
var/obj/effect/sliding_puzzle/source
var/icon/puzzle_icon
/obj/structure/puzzle_element/Move(nloc, dir)
if(!isturf(nloc) || moving_diagonally || get_dist(get_step(src,dir),get_turf(source)) > 1)
return 0
else
return ..()
/obj/structure/puzzle_element/proc/set_puzzle_icon()
cut_overlays()
if(puzzle_icon)
//Need to scale it down a bit to fit the static border
var/icon/C = new(puzzle_icon)
C.Scale(19,19)
var/mutable_appearance/puzzle_small = new(C)
puzzle_small.layer = layer + 0.1
puzzle_small.pixel_x = 7
puzzle_small.pixel_y = 7
add_overlay(puzzle_small)
/obj/structure/puzzle_element/Destroy()
if(source)
source.elements -= src
source.validate()
return ..()
//Set the full image on the turf and delete yourself
/obj/structure/puzzle_element/proc/collapse()
var/turf/T = get_turf(src)
var/mutable_appearance/MA = new(puzzle_icon)
MA.layer = T.layer + 0.1
T.add_overlay(MA)
//Some basic shaking animation
for(var/i in 1 to COLLAPSE_DURATION)
animate(src, pixel_x=rand(-5,5), pixel_y=rand(-2,2), time=1)
QDEL_IN(src,COLLAPSE_DURATION)
/obj/structure/puzzle_element/Moved()
. = ..()
source.validate()
//Admin abuse version so you can pick the icon before it sets up
/obj/effect/sliding_puzzle/admin
auto_setup = FALSE
var/icon/puzzle_icon
var/puzzle_state
/obj/effect/sliding_puzzle/admin/get_base_icon()
var/icon/I = new(puzzle_icon,puzzle_state)
return I
//Ruin version
/obj/effect/sliding_puzzle/lavaland
reward_type = /obj/structure/closet/crate/necropolis/puzzle
/obj/effect/sliding_puzzle/lavaland/dispense_reward()
if(prob(25))
//If it's not roaming somewhere else already.
var/mob/living/simple_animal/hostile/megafauna/bubblegum/B = locate() in GLOB.mob_list
if(!B)
reward_type = /mob/living/simple_animal/hostile/megafauna/bubblegum
return ..()
//Prison cube version
/obj/effect/sliding_puzzle/prison
auto_setup = FALSE //This will be done by cube proc
var/mob/living/prisoner
element_type = /obj/structure/puzzle_element/prison
/obj/effect/sliding_puzzle/prison/get_base_icon()
if(!prisoner)
CRASH("Prison cube without prisoner")
prisoner.setDir(SOUTH)
var/icon/I = getFlatIcon(prisoner)
I.Scale(96,96)
return I
/obj/effect/sliding_puzzle/prison/Destroy()
if(prisoner)
to_chat(prisoner,"<span class='userdanger'>With the cube broken by force, you can feel your body falling apart.</span>")
prisoner.death()
qdel(prisoner)
. = ..()
/obj/effect/sliding_puzzle/prison/dispense_reward()
prisoner.forceMove(get_turf(src))
prisoner.notransform = FALSE
prisoner = null
//Some armor so it's harder to kill someone by mistake.
/obj/structure/puzzle_element/prison
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 50, "acid" = 50)
/obj/structure/puzzle_element/prison/relaymove(mob/user)
return
/obj/item/prisoncube
name = "Prison Cube"
desc = "Dusty cube with humanoid imprint on it."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "prison_cube"
/obj/item/prisoncube/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!proximity_flag || !isliving(target))
return
var/mob/living/victim = target
var/mob/living/carbon/carbon_victim = victim
//Handcuffed or unconcious
if(istype(carbon_victim) && carbon_victim.handcuffed || victim.stat != CONSCIOUS)
if(!puzzle_imprison(target))
to_chat(user,"<span class='warning'>[src] does nothing.</span>")
return
to_chat(user,"<span class='warning'>You trap [victim] in the prison cube!</span>")
qdel(src)
else
to_chat(user,"<span class='notice'>[src] only accepts restrained or unconcious prisoners.</span>")
/proc/puzzle_imprison(mob/living/prisoner)
var/turf/T = get_turf(prisoner)
var/obj/effect/sliding_puzzle/prison/cube = new(T)
if(!cube.check_setup_location())
qdel(cube)
return FALSE
//First grab the prisoner and move them temporarily into the generator so they won't get thrown around.
prisoner.notransform = TRUE
prisoner.forceMove(cube)
to_chat(prisoner,"<span class='userdanger'>You're trapped by the prison cube! You will remain trapped until someone solves it.</span>")
//Clear the area from objects (and cube user)
var/list/things_to_throw = list()
for(var/atom/movable/AM in range(1,T))
if(!AM.anchored)
things_to_throw += AM
for(var/atom/movable/AM in things_to_throw)
var/throwtarget = get_edge_target_turf(T, get_dir(T, get_step_away(AM, T)))
AM.throw_at(throwtarget, 2, 3)
//Create puzzle itself
cube.prisoner = prisoner
cube.setup()
//Move them into random block
var/obj/structure/puzzle_element/E = pick(cube.elements)
prisoner.forceMove(E)
return TRUE
@@ -0,0 +1,156 @@
//These objects are used in the cardinal sin-themed ruins (i.e. Gluttony, Pride...)
// Greed
/obj/structure/cursed_slot_machine //Greed's slot machine: Used in the Greed ruin. Deals clone damage on each use, with a successful use giving a d20 of fate.
name = "greed's slot machine"
desc = "High stakes, high rewards."
icon = 'icons/obj/economy.dmi'
icon_state = "slots-off"
anchored = TRUE
density = TRUE
var/win_prob = 5
/obj/structure/cursed_slot_machine/attack_hand(mob/user)
interact(user)
/obj/structure/cursed_slot_machine/interact(mob/living/carbon/human/user)
if(!istype(user))
return
if(in_use)
return
in_use = TRUE
user.adjustCloneLoss(20)
if(user.stat)
to_chat(user, "<span class='userdanger'>No... just one more try...</span>")
user.gib()
else
user.visible_message("<span class='warning'>[user] pulls [src]'s lever with a glint in [user.p_their()] eyes!</span>", "<span class='warning'>You feel a draining as you pull the lever, but you \
know it'll be worth it.</span>")
icon_state = "slots-on"
playsound(src, 'sound/lavaland/cursed_slot_machine.ogg', 50, 0)
addtimer(CALLBACK(src, .proc/determine_victor, user), 50)
/obj/structure/cursed_slot_machine/proc/determine_victor(mob/living/user)
icon_state = "slots-off"
in_use = FALSE
if(prob(win_prob))
playsound(src, 'sound/lavaland/cursed_slot_machine_jackpot.ogg', 50, 0)
new/obj/structure/cursed_money(get_turf(src))
if(user)
to_chat(user, "<span class='boldwarning'>You've hit jackpot. Laughter echoes around you as your reward appears in the machine's place.</span>")
qdel(src)
else
if(user)
to_chat(user, "<span class='boldwarning'>Fucking machine! Must be rigged. Still... one more try couldn't hurt, right?</span>")
/obj/structure/cursed_money
name = "bag of money"
desc = "RICH! YES! YOU KNEW IT WAS WORTH IT! YOU'RE RICH! RICH! RICH!"
icon = 'icons/obj/storage.dmi'
icon_state = "moneybag"
anchored = FALSE
density = TRUE
/obj/structure/cursed_money/Initialize()
. = ..()
addtimer(CALLBACK(src, .proc/collapse), 600)
/obj/structure/cursed_money/proc/collapse()
visible_message("<span class='warning'>[src] falls in on itself, \
canvas rotting away and contents vanishing.</span>")
qdel(src)
/obj/structure/cursed_money/attack_hand(mob/living/user)
. = ..()
if(.)
return .
user.visible_message("<span class='warning'>[user] opens the bag and \
and removes a die. The bag then vanishes.</span>",
"<span class='boldwarning'>You open the bag...!</span>\n\
<span class='danger'>And see a bag full of dice. Confused, \
you take one... and the bag vanishes.</span>")
var/turf/T = get_turf(user)
var/obj/item/dice/d20/fate/one_use/critical_fail = new(T)
user.put_in_hands(critical_fail)
qdel(src)
// Gluttony
/obj/effect/gluttony //Gluttony's wall: Used in the Gluttony ruin. Only lets the overweight through.
name = "gluttony's wall"
desc = "Only those who truly indulge may pass."
anchored = TRUE
density = TRUE
icon_state = "blob"
icon = 'icons/mob/blob.dmi'
color = rgb(145, 150, 0)
/obj/effect/gluttony/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
if(ishuman(mover))
var/mob/living/carbon/human/H = mover
if(H.nutrition >= NUTRITION_LEVEL_FAT || (FAT in H.mutations))
H.visible_message("<span class='warning'>[H] pushes through [src]!</span>", "<span class='notice'>You've seen and eaten worse than this.</span>")
return TRUE
else
to_chat(H, "<span class='warning'>You're repulsed by even looking at [src]. Only a pig could force themselves to go through it.</span>")
if(istype(mover, /mob/living/simple_animal/hostile/morph))
return TRUE
else
return FALSE
// Pride
/obj/structure/mirror/magic/pride //Pride's mirror: Used in the Pride ruin.
name = "pride's mirror"
desc = "Pride cometh before the..."
icon_state = "magic_mirror"
/obj/structure/mirror/magic/pride/curse(mob/user)
user.visible_message("<span class='danger'><B>The ground splits beneath [user] as [user.p_their()] hand leaves the mirror!</B></span>", \
"<span class='notice'>Perfect. Much better! Now <i>nobody</i> will be able to resist yo-</span>")
var/turf/T = get_turf(user)
var/list/levels = space_manager.z_list.Copy()
for(var/level in levels)
if(!is_teleport_allowed(level))
levels -= level
T.ChangeTurf(/turf/simulated/floor/chasm)
var/turf/simulated/floor/chasm/C = T
C.drop_x = T.x
C.drop_y = T.y
C.drop_z = pick(levels)
C.drop(user)
// Envy
/obj/item/kitchen/knife/envy //Envy's knife: Found in the Envy ruin. Attackers take on the appearance of whoever they strike.
name = "envy's knife"
desc = "Their success will be yours."
icon = 'icons/obj/wizard.dmi'
icon_state = "render"
item_state = "knife"
force = 18
throwforce = 10
w_class = WEIGHT_CLASS_NORMAL
hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/kitchen/knife/envy/afterattack(atom/movable/AM, mob/living/carbon/human/user, proximity)
. = ..()
if(!proximity)
return
if(!istype(user))
return
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
if(user.real_name != H.dna.real_name)
user.real_name = H.dna.real_name
H.dna.transfer_identity(user)
user.visible_message("<span class='warning'>[user]'s appearance shifts into [H]'s!</span>", \
"<span class='boldannounce'>[H.p_they(TRUE)] think[H.p_s()] [H.p_theyre()] <i>sooo</i> much better than you. Not anymore, [H.p_they()] won't.</span>")
// Sloth
/obj/item/paper/fluff/stations/lavaland/sloth/note
name = "note from sloth"
icon_state = "paper_words"
info = "have not gotten around to finishing my cursed item yet sorry - sloth"