#nullable enable annotations
using System.Collections.Generic;
using Content.Shared.Preferences;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Observer;
using Content.Server.Interfaces.GameTicking;
using Content.Server.Players;
using Content.Server.Mobs;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.Components.Mobs;
using Content.Shared.GameObjects.Components.Mobs.State;
using Robust.Shared.Network;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.GameTicking
{
///
/// A round-start setup preset, such as which antagonists to spawn.
///
public abstract class GamePreset
{
public abstract bool Start(IReadOnlyList readyPlayers, bool force = false);
public virtual string ModeTitle => "Sandbox";
public virtual string Description => "Secret!";
public virtual bool DisallowLateJoin => false;
public Dictionary ReadyProfiles = new();
public virtual void OnGameStarted() { }
///
/// Called when a player is spawned in (this includes, but is not limited to, before Start)
///
public virtual void OnSpawnPlayerCompleted(IPlayerSession session, IEntity mob, bool lateJoin) { }
///
/// Called when a player attempts to ghost.
///
public virtual bool OnGhostAttempt(Mind mind, bool canReturnGlobal)
{
var playerEntity = mind.OwnedEntity;
if (playerEntity != null && playerEntity.HasComponent())
return false;
if (mind.VisitingEntity != null)
{
mind.UnVisit();
mind.VisitingEntity.Delete();
}
var position = playerEntity?.Transform.Coordinates ?? IoCManager.Resolve().GetObserverSpawnPoint();
var canReturn = false;
if (playerEntity != null && canReturnGlobal && playerEntity.TryGetComponent(out IMobStateComponent? mobState))
{
if (mobState.IsDead())
{
canReturn = true;
}
else if (mobState.IsCritical())
{
canReturn = true;
if (playerEntity.TryGetComponent(out IDamageableComponent? damageable))
{
//todo: what if they dont breathe lol
damageable.SetDamage(DamageType.Asphyxiation, 200, playerEntity);
}
}
else
{
canReturn = false;
}
}
var entityManager = IoCManager.Resolve();
var ghost = entityManager.SpawnEntity("MobObserver", position);
ghost.Name = mind.CharacterName;
var ghostComponent = ghost.GetComponent();
ghostComponent.CanReturnToBody = canReturn;
if (canReturn)
mind.Visit(ghost);
else
mind.TransferTo(ghost);
return true;
}
public virtual string GetRoundEndDescription() => "";
}
}