SANDBOX — this is a test environment. No servers are actually deployed and no real payments are charged.
Back to NxLabs

NxLabs / Vintage Story

Spawn In Bed

YBy YangWenLi

Re-spawn in any bed you've slept in. Emotional support drifter plushy not included.

Description

Sleeping in a bed sets your spawn point to it. Just that. Works with modded beds!
Made because the usual mods for this aren't working on the latest version, so I took it upon myself to make my own implementation.

 

Source Code (Sorry, too lazy to put this on github lol)
<pre class="language-csharp">using System; using System.Collections.Generic; using Vintagestory.API.Common; using Vintagestory.API.Common.Entities; using Vintagestory.API.Datastructures; using Vintagestory.API.Server;

namespace YangBed { public sealed class YangBedModSystem : ModSystem { private ICoreServerAPI sapi; private readonly Dictionary&lt;string, Action&gt; mountListenersByPlayerUid = new Dictionary&lt;string, Action&gt;();

public override bool ShouldLoad(EnumAppSide forSide) { return forSide == EnumAppSide.Server; }

public override void StartServerSide(ICoreServerAPI api) { sapi = api;

sapi.Event.PlayerNowPlaying += OnPlayerNowPlaying; sapi.Event.PlayerDisconnect += OnPlayerDisconnect; }

private void OnPlayerNowPlaying(IServerPlayer player) { if (player == null || player.Entity == null) return;

UnregisterPlayer(player); string playerUid = player.PlayerUID;

// Beds set tiredness.isSleeping via an enqueued task during mount, one-shot callback. No need to check anything each tick or something stupid like that. Action listener = () =&gt; { sapi.Event.RegisterCallback(_ =&gt; TrySetSpawnFromSleep(playerUid), 50); };

mountListenersByPlayerUid[playerUid] = listener; player.Entity.WatchedAttributes.RegisterModifiedListener("mountedOn", listener); }

private void OnPlayerDisconnect(IServerPlayer player) { if (player == null) return; UnregisterPlayer(player); }

private void UnregisterPlayer(IServerPlayer player) { if (!mountListenersByPlayerUid.TryGetValue(player.PlayerUID, out Action listener)) return;

player.Entity?.WatchedAttributes.UnregisterListener(listener); mountListenersByPlayerUid.Remove(player.PlayerUID); }

private void TrySetSpawnFromSleep(string playerUid) { IServerPlayer player = sapi.World.PlayerByUid(playerUid) as IServerPlayer; if (player == null || player.Entity == null) return;

EntityPlayer entity = player.Entity; if (entity.MountedOn == null || !IsSleeping(entity)) return;

EntityPos seatPos = entity.MountedOn.SeatPosition ?? entity.Pos; player.SetSpawnPosition(new PlayerSpawnPos { x = (int)Math.Floor(seatPos.X), y = (int)Math.Ceiling(seatPos.InternalY), z = (int)Math.Floor(seatPos.Z), yaw = seatPos.Yaw, pitch = 0f, roll = 0f, RemainingUses = -1 });

player.SendIngameError("yangbed-confirm", "Re-spawn Point Set..."); }

private static bool IsSleeping(EntityPlayer entity) { ITreeAttribute tiredness = entity.WatchedAttributes.GetTreeAttribute("tiredness"); return tiredness != null &amp;&amp; tiredness.GetInt("isSleeping") &gt; 0; }

public override void Dispose() { if (sapi != null) { sapi.Event.PlayerNowPlaying -= OnPlayerNowPlaying; sapi.Event.PlayerDisconnect -= OnPlayerDisconnect; foreach (IPlayer player in sapi.World.AllOnlinePlayers) { if (player is IServerPlayer serverPlayer) { UnregisterPlayer(serverPlayer); } } }

mountListenersByPlayerUid.Clear(); base.Dispose(); } } }</pre>

&nbsp;

Ratings & reviews

No ratings yet

Sign in to leave a rating or comment.