Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

a bedtime update for beddy-bye boys (Bunk beds!) #3345

Merged
merged 4 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions code/datums/elements/bed_tucking.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,22 @@
var/y_offset = 0
/// our rotation degree - how much the item turns when in bed (+degrees turns it more parallel)
var/rotation_degree = 0
/// Whether the item changes its dir to match the desired lying direction of the bed that it's tucked into.
var/change_dir = FALSE
/// Whether the item changes its layer to the layer suggested by the bed for tucked-in item.
/// When the item is untucked, it is returned to its initial() layer.
var/change_layer = FALSE

/datum/element/bed_tuckable/Attach(obj/target, x = 0, y = 0, rotation = 0)
/datum/element/bed_tuckable/Attach(obj/target, x = 0, y = 0, rotation = 0, _change_dir = FALSE, _change_layer = FALSE)
. = ..()
if(!isitem(target))
return ELEMENT_INCOMPATIBLE

x_offset = x
y_offset = y
rotation_degree = rotation
change_dir = _change_dir
change_layer = _change_layer
RegisterSignal(target, COMSIG_ITEM_ATTACK_OBJ, PROC_REF(tuck_into_bed))

/datum/element/bed_tuckable/Detach(obj/target)
Expand All @@ -40,11 +47,20 @@
return

to_chat(tucker, "<span class='notice'>You lay [tucked] out on [target_bed].</span>")
tucked.pixel_x = x_offset
tucked.pixel_y = y_offset
tucked.pixel_x = x_offset + target_bed.tucked_x_shift
tucked.pixel_y = y_offset + target_bed.tucked_y_shift
if(rotation_degree)
tucked.transform = turn(tucked.transform, rotation_degree)
RegisterSignal(tucked, COMSIG_ITEM_PICKUP, PROC_REF(untuck))
// the buckle_lying value on the bed controls the direction that mobs lay down in when they're buckled into bed.
// some items (bedsheets) have different states to reflect those directions.
if(change_dir)
if(target_bed.buckle_lying == 270)
tucked.setDir(NORTH)
else
tucked.setDir(SOUTH)
if(target_bed.suggested_tuck_layer != null)
tucked.layer = target_bed.suggested_tuck_layer

return COMPONENT_NO_AFTERATTACK

Expand All @@ -57,4 +73,5 @@
SIGNAL_HANDLER

tucked.transform = turn(tucked.transform, -rotation_degree)
tucked.layer = initial(tucked.layer)
UnregisterSignal(tucked, COMSIG_ITEM_PICKUP)
2 changes: 1 addition & 1 deletion code/game/objects/items/plushes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
. = ..()
if(should_squeak)
AddComponent(/datum/component/squeak, squeak_override)
AddElement(/datum/element/bed_tuckable, 6, -5, 90)
AddElement(/datum/element/bed_tuckable, 6, -5, 90, FALSE, FALSE)

//have we decided if Pinocchio goes in the blue or pink aisle yet?
if(gender == NEUTER)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
GLOBAL_LIST_INIT(metal_recipes, list ( \
new/datum/stack_recipe("stool", /obj/structure/chair/stool, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("bar stool", /obj/structure/chair/stool/bar, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("double bed", /obj/structure/bed/double, 4, one_per_turf = TRUE, on_floor = TRUE), \
null, \
new/datum/stack_recipe_list("beds", list( \
new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("double bed", /obj/structure/bed/double, 4, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("bottom bunk", /obj/structure/bed/bunk, 2, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("top bunk", /obj/structure/bed/bunk/top, 2, one_per_turf = TRUE, on_floor = TRUE), \
)), \
new/datum/stack_recipe_list("office chairs", list( \
new/datum/stack_recipe("gray office chair", /obj/structure/chair/office, 5, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("light office chair", /obj/structure/chair/office/light, 5, one_per_turf = TRUE, on_floor = TRUE), \
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/stacks/stack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@
if(!window_structure.fulltile)
continue
if(object.density)
to_chat(usr, "<span class='warning'>There is \a [object.name] here. You cant make \a [recipe.title] here!</span>")
to_chat(usr, "<span class='warning'>There is \a [object.name] here. You can't make \a [recipe.title] here!</span>")
return FALSE
if(recipe.placement_checks)
switch(recipe.placement_checks)
Expand Down
1 change: 1 addition & 0 deletions code/game/objects/structures/beds_chairs/alien_nest.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
buildstacktype = null
flags_1 = NODECONSTRUCT_1
bolts = FALSE
swap_lying_with_dir = FALSE
var/static/mutable_appearance/nest_overlay = mutable_appearance('icons/mob/alien.dmi', "nestoverlay", LYING_MOB_LAYER)

/obj/structure/bed/nest/user_unbuckle_mob(mob/living/buckled_mob, mob/living/user)
Expand Down
130 changes: 127 additions & 3 deletions code/game/objects/structures/beds_chairs/bed.dm
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,44 @@
resistance_flags = FLAMMABLE
max_integrity = 100
integrity_failure = 0.35

var/buildstacktype = /obj/item/stack/sheet/metal
var/buildstackamount = 2
var/bolts = TRUE

/// Whether the bed changes its buckle_lying direction
/// (and accordingly the direction in which mobs lie down) based on its current direction.
var/swap_lying_with_dir = TRUE
/// If non-null, some items (bedsheets) which can be tucked into beds
/// will set their layer to this value when they are tucked in, until they are picked up again.
var/suggested_tuck_layer = null
/// The amount added to the pixel_x value of a tucked-in item.
var/tucked_x_shift = 0
/// The amount added to the pixel_y value of a tucked-in item.
var/tucked_y_shift = 0

/obj/structure/bed/Initialize(...)
. = ..()
if(swap_lying_with_dir)
buckle_lying = get_buckle_angle_from_dir(dir)

/obj/structure/bed/setDir(newdir)
. = ..()
if(swap_lying_with_dir)
buckle_lying = get_buckle_angle_from_dir(newdir)
// shuttle rotation etc... ugh.
if(has_buckled_mobs())
for(var/mob/living/M as anything in buckled_mobs)
// this proc already checks to see if the new angle is different from the old one,
// so this shouldn't cause any duplicate work or unnecessary animations.
M.set_lying_angle(buckle_lying)

/obj/structure/bed/proc/get_buckle_angle_from_dir(some_dir)
if(some_dir & (SOUTH|WEST))
return 90
else
return 270

/obj/structure/bed/examine(mob/user)
. = ..()
if(bolts)
Expand Down Expand Up @@ -52,6 +86,9 @@
icon_state = "down"
anchored = FALSE
resistance_flags = NONE

// no dir states
swap_lying_with_dir = FALSE
var/foldabletype = /obj/item/roller

/obj/structure/bed/roller/attackby(obj/item/W, mob/user, params)
Expand Down Expand Up @@ -161,15 +198,19 @@
else
to_chat(user, "<span class='warning'>The dock is empty!</span>")

//Dog bed

/*
* "Dog" beds
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like those quotes.....

*/
/obj/structure/bed/dogbed
name = "dog bed"
icon_state = "dogbed"
desc = "A comfy-looking dog bed. You can even strap your pet in, in case the gravity turns off."
anchored = TRUE
buildstacktype = /obj/item/stack/sheet/mineral/wood
buildstackamount = 10

// no dir states
swap_lying_with_dir = FALSE
var/mob/living/owner = null

/obj/structure/bed/dogbed/ian
Expand Down Expand Up @@ -206,7 +247,9 @@
. = ..()
update_owner(M)

//Double Beds, for luxurious sleeping, i.e. the captain and maybe heads - no quirky refrence here. Move along
/*
* Double beds, for luxurious sleeping, i.e. the captain and maybe heads - no quirky refrence here. Move along
*/
/obj/structure/bed/double
name = "double bed"
desc = "A luxurious double bed, for those too important for small dreams."
Expand All @@ -232,3 +275,84 @@
name = "double dirty mattress"
desc = "An old grubby king sized mattress. You really try to not think about what could be the cause of those stains."
icon_state = "dirty_mattress_double"

/*
* Bunk beds. Comes with an /obj/effect spawner that lets mappers place them down easily.
* The base type is the bottom bunk, with the top bunk as a derived type.
* Like other beds, the pillow may be on the left or right depending on the direction.
*/
/obj/structure/bed/bunk
name = "bottom bunk"
desc = "The oft-maligned bottom bunk of a compact bunk bed. Heavy sleepers only."
icon_state = "bottom_bunk"
// just below the top bunk's main layer
suggested_tuck_layer = LYING_MOB_LAYER + 0.005
/// The amount added to the pixel_y value of mobs lying down, relative to the default shift for that position.
var/mob_y_shift = -1
// i think it looks best without shifting the bedsheet down, even though the mob gets shifted down some

// alter their pixel offset when they lie down...
/obj/structure/bed/bunk/post_buckle_mob(mob/living/M)
// we shift the lying mob a little so that they line up better with the pillow, but the shift direction changes
// depending on the direction they lie down in, controlled by buckle_lying
// (which is in turn based on our direction, but we don't need to worry about that directly)
var/horz_offset
if(buckle_lying == 90)
horz_offset = 2
else
horz_offset = -2

M.pixel_x = M.get_standard_pixel_x_offset(M.body_position == LYING_DOWN) + horz_offset
M.pixel_y = M.get_standard_pixel_y_offset(M.body_position == LYING_DOWN) + mob_y_shift

// ...and reset it when they get off
/obj/structure/bed/bunk/post_unbuckle_mob(mob/living/M)
M.pixel_x = M.get_standard_pixel_x_offset(M.body_position == LYING_DOWN)
M.pixel_y = M.get_standard_pixel_y_offset(M.body_position == LYING_DOWN)


/obj/structure/bed/bunk/top
name = "top bunk"
desc = "The top bunk of a compact bunk bed. Few other sleeping accommodations can match its luxury."
icon_state = "top_bunk"

// higher layer, so that it renders on top of people on the bottom bunk
layer = LYING_MOB_LAYER + 0.01
mob_y_shift = 13

// above the lying mob, but below the ladder
suggested_tuck_layer = LYING_MOB_LAYER + 0.025
tucked_y_shift = 14

/obj/structure/bed/bunk/top/Initialize(...)
. = ..()
// the ladder needs to render above the mob
overlays += image(icon = 'icons/obj/objects.dmi', icon_state = "top_bunk_ladder", layer = LYING_MOB_LAYER + 0.03)
// and the posts need to render below the bottom bunk
overlays += image(icon = 'icons/obj/objects.dmi', icon_state = "top_bunk_posts", layer = TABLE_LAYER)

/obj/structure/bed/bunk/top/post_buckle_mob(mob/living/M)
. = ..()
M.layer = LYING_MOB_LAYER + 0.02

/obj/structure/bed/bunk/top/post_unbuckle_mob(mob/living/M)
. = ..()
// honestly not really confident in this, but since standing up takes a do_after
// (and thus happens afterwards, resetting the layer), it should be fine...
// i'm more worried about altering layers via + and -, since if you figured out ways
// of stacking those you could layer yourself under, like, the floor.
M.layer = LYING_MOB_LAYER


// the spawner
/obj/effect/spawner/bunk_bed
name = "bunk bed spawner"
icon_state = "bunk_bed_spawner"

/obj/effect/spawner/bunk_bed/Initialize(...)
. = ..()
var/obj/structure/bed/bunk/bottom_bunk = new(loc)
var/obj/structure/bed/bunk/top/top_bunk = new(loc)

bottom_bunk.setDir(dir)
top_bunk.setDir(dir)
2 changes: 1 addition & 1 deletion code/game/objects/structures/bedsheet_bin.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ LINEN BINS

/obj/item/bedsheet/Initialize(mapload)
. = ..()
AddElement(/datum/element/bed_tuckable, 0, 0, 0)
AddElement(/datum/element/bed_tuckable, 0, 0, 0, TRUE, TRUE)

/obj/item/bedsheet/attack_self(mob/user)
if(!user.CanReach(src)) //No telekenetic grabbing.
Expand Down
6 changes: 3 additions & 3 deletions code/game/objects/structures/tank_dispenser.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
/obj/structure/tank_dispenser/update_overlays()
. = ..()
switch(oxygentanks)
if(1 to 3)
if(1 to 4)
. += "oxygen-[oxygentanks]"
if(4 to TANK_DISPENSER_CAPACITY)
. += "oxygen-4"
if(5 to TANK_DISPENSER_CAPACITY)
. += "oxygen-5"
switch(plasmatanks)
if(1 to 4)
. += "plasma-[plasmatanks]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
icon = 'icons/obj/abductor.dmi'
buildstacktype = /obj/item/stack/sheet/mineral/abductor
icon_state = "bed"
swap_lying_with_dir = FALSE

/obj/structure/table_frame/abductor
name = "alien table frame"
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ This is here to make the tiles around the station mininuke change when it's arme

/obj/item/disk/nuclear/Initialize()
. = ..()
AddElement(/datum/element/bed_tuckable, 6, -6, 0)
AddElement(/datum/element/bed_tuckable, 6, -6, 0, FALSE, FALSE)

if(!fake)
GLOB.poi_list |= src
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/carbon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@

/mob/living/carbon/get_standard_pixel_y_offset(lying = 0)
if(lying)
return -6
return PIXEL_Y_OFFSET_LYING
else
return initial(pixel_y)

Expand Down
Binary file modified icons/effects/effects.dmi
Binary file not shown.
Binary file modified icons/obj/objects.dmi
Binary file not shown.
Loading