mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
191 lines
5.1 KiB
Plaintext
191 lines
5.1 KiB
Plaintext
//Pop-out cake!
|
|
//A huge cake that can fit a person inside
|
|
//You can cut the cake up to 16 times to receive a cake slice. After that the cake is destroyed and a large cardboard box is left
|
|
|
|
//LOCKING CATEGORY FOR OBJECTS THAT ARE CLIMBING OUT OF THE CAKE
|
|
/datum/locking_category/popout_cake
|
|
pixel_y_offset = 1 //First row of pixels on the cake is transparent :^
|
|
|
|
var/pixel_y_offset_max = 24 * PIXEL_MULTIPLIER
|
|
|
|
/datum/locking_category/popout_cake/lock(atom/movable/AM)
|
|
pixel_y_offset -= AM.pixel_y
|
|
pixel_x_offset -= AM.pixel_x
|
|
|
|
//AM.pixel_y = 0
|
|
//AM.pixel_x = 0
|
|
|
|
..()
|
|
|
|
owner.plane = AM.plane
|
|
owner.layer = AM.layer + 0.1
|
|
animate(AM, pixel_y = pixel_y_offset_max + AM.pixel_y, 40) //Increase pixel_y over 4 seconds
|
|
|
|
/datum/locking_category/popout_cake/unlock(atom/movable/AM)
|
|
..()
|
|
|
|
animate(AM) //Stop the animation
|
|
AM.pixel_y -= pixel_y_offset_max * PIXEL_MULTIPLIER
|
|
|
|
owner.reset_plane_and_layer()
|
|
|
|
/obj/structure/popout_cake
|
|
name = "large cake"
|
|
desc = "An enormous multi-tiered cake."
|
|
|
|
icon_state = "popout_cake"
|
|
|
|
anchored = 0
|
|
opacity = 0
|
|
density = 1
|
|
|
|
var/slices_amount = 16
|
|
var/string_pulled = 0
|
|
|
|
/obj/structure/popout_cake/Destroy()
|
|
for(var/mob/living/L in get_locked(/datum/locking_category/popout_cake) + contents) //Release all mobs inside
|
|
relaymove(L, NORTH)
|
|
|
|
..()
|
|
|
|
/obj/structure/popout_cake/examine(mob/user)
|
|
.=..()
|
|
|
|
user.show_message("<span class='info'>There are [slices_amount] slices remaining.</span>", MESSAGE_SEE)
|
|
|
|
/obj/structure/popout_cake/attack_hand(mob/living/user)
|
|
if(user.loc == src) //Clicked from inside the cake
|
|
pull_string()
|
|
return
|
|
else if(locate(/mob/living) in contents)
|
|
to_chat(user, "<span class='info'>There appears to be something inside of \the [src]!</span>")
|
|
return
|
|
|
|
user.visible_message("<span class='notice'>[user] starts climbing into \the [src]!</span>")
|
|
if(do_after(user, src, 60))
|
|
if(locate(/mob/living) in contents)
|
|
to_chat(user, "<span class='info'>There appears to be something inside of \the [src]!</span>")
|
|
return
|
|
user.forceMove(src)
|
|
to_chat(user, "<span class='info'>You are now inside the cake! When you're ready to emerge from the cake in a blaze of confetti and party horns, pull on the string by clicking on \the [src] (<b>this can only be done once</b>). If you wish to leave without setting off the confetti, just attempt to move out of the cake!</span>")
|
|
|
|
/obj/structure/popout_cake/attack_slime(mob/user)
|
|
return attack_hand(user)
|
|
|
|
/obj/structure/popout_cake/attack_paw(mob/user)
|
|
return attack_hand(user)
|
|
|
|
/obj/structure/popout_cake/attackby(obj/item/W, mob/user)
|
|
if(W.sharpness_flags & SHARP_BLADE)
|
|
user.visible_message("<span class='notice'>[user] starts cutting a slice from \the [src].</span>")
|
|
|
|
spawn() //So that the proc can return 1, delaying the next attack
|
|
if(do_after(user, src, 10))
|
|
drop_slice()
|
|
check_slices()
|
|
|
|
return 1
|
|
|
|
/obj/structure/popout_cake/proc/drop_slice()
|
|
slices_amount--
|
|
|
|
return new /obj/item/weapon/reagent_containers/food/snacks/plaincakeslice/full(get_turf(src))
|
|
|
|
/obj/structure/popout_cake/proc/check_slices()
|
|
if(slices_amount <= 0)
|
|
new /obj/item/weapon/storage/box/large(get_turf(src))
|
|
|
|
qdel(src)
|
|
|
|
/obj/structure/popout_cake/proc/pull_string()
|
|
set name = "Pull Party String"
|
|
set desc = "Activate a simple mechanism that lifts you out of the cake. This can only be done once!"
|
|
set category = "Object"
|
|
set src = usr.loc
|
|
|
|
if(!isturf(loc))
|
|
return
|
|
|
|
var/mob/living/L = usr
|
|
if(!istype(L))
|
|
return
|
|
|
|
if(L.incapacitated())
|
|
return
|
|
|
|
if(string_pulled)
|
|
to_chat(L, "<span class='info'>The string has already been pulled!</span>")
|
|
return
|
|
|
|
to_chat(L, "<span class='info'>You pull on the party string!</span>")
|
|
|
|
release_object(L)
|
|
|
|
string_pulled = 1
|
|
|
|
/obj/structure/popout_cake/proc/release_object(var/atom/L, var/drop = FALSE)
|
|
if(!L)
|
|
if(!src.contents.len)
|
|
return
|
|
|
|
L = pick(src.contents)
|
|
|
|
visible_message("<span class='notice'>All of a sudden, something emerges from \the [src]!</span>")
|
|
|
|
lock_atom(L, /datum/locking_category/popout_cake)
|
|
|
|
spawn(10)
|
|
|
|
playsound(src, 'sound/effects/party_horn.ogg', 50, 1)
|
|
|
|
sleep(10)
|
|
|
|
//Idea for the future: put actual confetti here
|
|
spark(src, 6, FALSE)
|
|
|
|
if(drop)
|
|
sleep(20)
|
|
|
|
unlock_atom(L)
|
|
|
|
/obj/structure/popout_cake/relaymove(mob/living/L, direction)
|
|
if(!istype(L))
|
|
return
|
|
|
|
if(L in get_locked(/datum/locking_category/popout_cake))
|
|
unlock_atom(L)
|
|
else if(contents.Find(L))
|
|
L.forceMove(get_turf(src))
|
|
|
|
/obj/structure/popout_cake/kick_act(mob/user)
|
|
.=..()
|
|
|
|
slices_amount -= rand(1,3) //Deal some damage
|
|
check_slices()
|
|
|
|
/obj/structure/popout_cake/bite_act(mob/user)
|
|
var/obj/item/I = drop_slice()
|
|
I.bite_act(user)
|
|
|
|
check_slices()
|
|
|
|
/obj/structure/popout_cake/bullet_act(var/obj/item/projectile/Proj)
|
|
slices_amount -= clamp(round(Proj.damage / 3), 1, 4)
|
|
check_slices()
|
|
return ..()
|
|
|
|
//When spawned, stuffs the corpse underneath it inside
|
|
/obj/structure/popout_cake/corpse_grabber/New()
|
|
..()
|
|
|
|
initialize()
|
|
|
|
/obj/structure/popout_cake/corpse_grabber/initialize()
|
|
..()
|
|
|
|
spawn(40) //Search for a corpse after a slight delay, because corpse spawners are objects, and don't spawn the corpse immediately
|
|
for(var/mob/living/L in loc)
|
|
if(L.isDead())
|
|
L.forceMove(src)
|
|
break
|