2020-12-11 01:10:55 +00:00
#nullable enable annotations
2020-12-14 16:46:56 +01:00
using System.Collections.Generic ;
2021-06-09 22:19:39 +02:00
using Content.Server.Ghost.Components ;
2020-12-11 01:10:55 +00:00
using Content.Shared.Damage ;
2021-06-09 22:19:39 +02:00
using Content.Shared.Damage.Components ;
using Content.Shared.MobState ;
2021-03-16 15:50:20 +01:00
using Content.Shared.Preferences ;
2021-02-11 01:13:03 -08:00
using Robust.Server.Player ;
using Robust.Shared.GameObjects ;
2020-12-11 01:10:55 +00:00
using Robust.Shared.IoC ;
2021-03-16 15:50:20 +01:00
using Robust.Shared.Network ;
2020-05-03 11:25:39 +02:00
2021-06-09 22:19:39 +02:00
namespace Content.Server.GameTicking.Presets
2018-11-22 10:37:58 +01:00
{
/// <summary>
/// A round-start setup preset, such as which antagonists to spawn.
/// </summary>
public abstract class GamePreset
{
2020-06-21 22:05:47 +02:00
public abstract bool Start ( IReadOnlyList < IPlayerSession > readyPlayers , bool force = false ) ;
2020-04-08 06:07:54 -05:00
public virtual string ModeTitle = > "Sandbox" ;
2019-10-18 14:28:39 +02:00
public virtual string Description = > "Secret!" ;
2020-08-20 16:20:48 +02:00
public virtual bool DisallowLateJoin = > false ;
2020-12-16 10:00:10 +01:00
public Dictionary < NetUserId , HumanoidCharacterProfile > ReadyProfiles = new ( ) ;
2020-12-01 17:05:19 +01:00
public virtual void OnGameStarted ( ) { }
2020-12-11 01:10:55 +00:00
/// <summary>
/// Called when a player is spawned in (this includes, but is not limited to, before Start)
/// </summary>
public virtual void OnSpawnPlayerCompleted ( IPlayerSession session , IEntity mob , bool lateJoin ) { }
/// <summary>
/// Called when a player attempts to ghost.
/// </summary>
2021-06-09 22:19:39 +02:00
public virtual bool OnGhostAttempt ( Mind . Mind mind , bool canReturnGlobal )
2020-12-11 01:10:55 +00:00
{
var playerEntity = mind . OwnedEntity ;
if ( playerEntity ! = null & & playerEntity . HasComponent < GhostComponent > ( ) )
return false ;
if ( mind . VisitingEntity ! = null )
{
mind . UnVisit ( ) ;
}
2021-06-20 10:09:24 +02:00
var position = playerEntity ? . Transform . Coordinates ? ? EntitySystem . Get < GameTicker > ( ) . GetObserverSpawnPoint ( ) ;
2021-06-03 09:03:19 +01:00
// Ok, so, this is the master place for the logic for if ghosting is "too cheaty" to allow returning.
// There's no reason at this time to move it to any other place, especially given that the 'side effects required' situations would also have to be moved.
// + If CharacterDeadPhysically applies, we're physically dead. Therefore, ghosting OK, and we can return (this is critical for gibbing)
// Note that we could theoretically be ICly dead and still physically alive and vice versa.
// (For example, a zombie could be dead ICly, but may retain memories and is definitely physically active)
// + If we're in a mob that is critical, and we're supposed to be able to return if possible,
/// we're succumbing - the mob is killed. Therefore, character is dead. Ghosting OK.
// (If the mob survives, that's a bug. Ghosting is kept regardless.)
var canReturn = canReturnGlobal & & mind . CharacterDeadPhysically ;
2020-12-11 01:10:55 +00:00
if ( playerEntity ! = null & & canReturnGlobal & & playerEntity . TryGetComponent ( out IMobStateComponent ? mobState ) )
{
2021-06-03 09:03:19 +01:00
if ( mobState . IsCritical ( ) )
2020-12-11 01:10:55 +00:00
{
canReturn = true ;
if ( playerEntity . TryGetComponent ( out IDamageableComponent ? damageable ) )
{
//todo: what if they dont breathe lol
2021-01-10 20:52:11 +01:00
damageable . SetDamage ( DamageType . Asphyxiation , 200 , playerEntity ) ;
2020-12-11 01:10:55 +00:00
}
}
}
var entityManager = IoCManager . Resolve < IEntityManager > ( ) ;
var ghost = entityManager . SpawnEntity ( "MobObserver" , position ) ;
2021-03-16 15:50:20 +01:00
ghost . Name = mind . CharacterName ? ? string . Empty ;
2020-12-11 01:10:55 +00:00
var ghostComponent = ghost . GetComponent < GhostComponent > ( ) ;
ghostComponent . CanReturnToBody = canReturn ;
if ( canReturn )
mind . Visit ( ghost ) ;
else
mind . TransferTo ( ghost ) ;
return true ;
}
2020-12-01 17:05:19 +01:00
public virtual string GetRoundEndDescription ( ) = > "" ;
2018-11-22 10:37:58 +01:00
}
}