2020-12-22 03:13:43 +00:00
/ * This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at https : //mozilla.org/MPL/2.0/. */
using System ;
2020-11-27 22:47:33 +00:00
using System.Collections ;
using System.Collections.Generic ;
using System.IO ;
2020-12-12 03:42:58 +00:00
using System.Linq ;
2020-11-29 22:50:12 +00:00
using Cinemachine ;
2021-04-19 04:35:46 +01:00
using Ink ;
using Ink.Runtime ;
2020-11-27 22:47:33 +00:00
using MessagePack ;
2020-12-14 02:56:35 +00:00
using TMPro ;
2020-11-29 22:50:12 +00:00
using UniRx ;
2020-11-27 22:47:33 +00:00
using UnityEngine ;
2020-12-02 16:42:09 +00:00
using UnityEngine.InputSystem ;
2021-03-06 02:42:19 +00:00
using UnityEngine.Rendering.PostProcessing ;
2021-03-15 11:40:46 +00:00
using UnityEngine.Serialization ;
2020-12-14 02:56:35 +00:00
using UnityEngine.UI ;
2021-03-15 11:40:46 +00:00
using Unity.Mathematics ;
2021-04-11 16:11:06 +01:00
using UnityEngine.EventSystems ;
2020-11-27 22:47:33 +00:00
using static Unity . Mathematics . math ;
using float2 = Unity . Mathematics . float2 ;
2021-03-18 00:36:34 +00:00
using float3 = Unity . Mathematics . float3 ;
2021-04-19 04:35:46 +01:00
using Path = System . IO . Path ;
2021-03-05 14:31:18 +00:00
using quaternion = Unity . Mathematics . quaternion ;
2021-02-11 03:14:20 +00:00
using Random = UnityEngine . Random ;
2020-11-27 22:47:33 +00:00
public class ActionGameManager : MonoBehaviour
{
2022-07-21 21:40:44 +01:00
// Always check for null if accessing from anywhere that might not be in-game (e.g. menu UI)
2021-04-12 04:20:52 +01:00
public static ActionGameManager Instance { get ; private set ; }
2021-03-15 11:40:46 +00:00
private static DirectoryInfo _gameDataDirectory ;
2021-03-14 03:56:49 +00:00
public static DirectoryInfo GameDataDirectory
{
get = > _gameDataDirectory ? ? = new DirectoryInfo ( Application . dataPath ) . Parent . CreateSubdirectory ( "GameData" ) ;
}
2021-03-15 11:40:46 +00:00
2026-06-13 01:59:17 +01:00
public static string AetheriaStateFilePath = > Path . Combine ( GameDataDirectory . FullName , "aetheria-world.cc" ) ;
public static string LegacyAetherDatabasePath = > Path . Combine ( GameDataDirectory . FullName , "AetherDB.msgpack" ) ;
2021-03-15 11:40:46 +00:00
2026-06-13 01:59:17 +01:00
private static CultCache _legacyCultCache ;
public static CultCache LegacyCultCache
2021-03-15 11:40:46 +00:00
{
get
{
2026-06-13 01:59:17 +01:00
if ( _legacyCultCache ! = null ) return _legacyCultCache ;
2021-03-15 11:40:46 +00:00
2026-06-13 01:59:17 +01:00
_legacyCultCache = new CultCache ( ) ;
_legacyCultCache . AddBackingStore (
new SingleFileMessagePackBackingStore ( LegacyAetherDatabasePath ) ) ;
2022-07-21 21:40:44 +01:00
// Particularly heavy objects should be stored in / retrieved from MsgPack files as it's much tighter than JSON
// Such as NameFiles, which are just huge collections of geonames used to condition Markov chains
2026-06-13 01:59:17 +01:00
_legacyCultCache . AddBackingStore ( new MultiFileMessagePackBackingStore ( GameDataDirectory . FullName ) , typeof ( NameFile ) ) ;
2022-07-21 21:40:44 +01:00
2026-06-13 01:59:17 +01:00
_legacyCultCache . PullAllBackingStores ( ) ;
2021-03-15 11:40:46 +00:00
2026-06-13 01:59:17 +01:00
return _legacyCultCache ;
2021-03-15 11:40:46 +00:00
}
}
2026-06-13 01:59:17 +01:00
[Obsolete("Use LegacyCultCache only for migration-era catalog reads. Live state belongs in GameData/aetheria-world.cc through Aetheria.State.")]
public static CultCache CultCache = > LegacyCultCache ;
2021-03-15 11:40:46 +00:00
private static PlayerSettings _playerSettings ;
2021-03-14 03:56:49 +00:00
public static PlayerSettings PlayerSettings
{
2021-05-07 19:51:23 +01:00
get
{
RegisterResolver . Register ( ) ;
2026-06-13 05:21:22 +01:00
return _playerSettings ? ? = GetDefaultPlayerSettings ( ) ;
2021-05-07 19:51:23 +01:00
}
2021-03-14 03:56:49 +00:00
}
2021-05-07 19:51:23 +01:00
2021-03-14 03:56:49 +00:00
public static void SavePlayerSettings ( )
{
2026-06-13 05:21:22 +01:00
Debug . LogWarning ( "Player settings persistence belongs to the Verse state spine. The Unity client keeps settings in memory until Aetheria.State is available as a runtime package." ) ;
2021-03-14 03:56:49 +00:00
}
2021-03-15 11:40:46 +00:00
2021-05-06 18:43:23 +01:00
private static PlayerSettings GetDefaultPlayerSettings ( )
{
var settings = new PlayerSettings ( ) ;
settings . Name = Environment . UserName ;
settings . InputSettings . ActionBarInputs . Add ( "<Keyboard>/leftShift" ) ;
settings . InputSettings . ActionBarInputs . Add ( "<Mouse>/leftButton" ) ;
settings . InputSettings . ActionBarInputs . Add ( "<Mouse>/rightButton" ) ;
settings . InputSettings . ActionBarInputs . Add ( "<Mouse>/middleButton" ) ;
for ( int i = 1 ; i < 6 ; i + + ) settings . InputSettings . ActionBarInputs . Add ( $"<Keyboard>/{i}" ) ;
return settings ;
}
2021-05-14 03:03:28 +01:00
public static Galaxy CurrentGalaxy ;
2021-04-22 02:53:06 +01:00
public static bool IsTutorial ;
2021-04-18 05:13:20 +01:00
2021-03-10 09:18:07 +00:00
public GameSettings Settings ;
2021-03-18 22:48:33 +00:00
//public string StarterShipTemplate = "Longinus";
2021-03-10 09:18:07 +00:00
public float2 Sensitivity ;
public int Credits = 15000000 ;
2021-03-07 23:24:22 +00:00
public float TargetSpottedBlinkFrequency = 20 ;
public float TargetSpottedBlinkOffset = - . 25f ;
2021-03-10 09:18:07 +00:00
[Header("Postprocessing")]
2021-05-14 03:03:28 +01:00
public float DeathPostTransitionTime ;
public PostProcessVolume DeathPost ;
public PostProcessVolume HeatstrokePost ;
public PostProcessVolume HypothermiaPost ;
public PostProcessVolume SevereHeatstrokePost ;
public PostProcessVolume SevereHypothermiaPost ;
2021-03-20 04:20:17 +00:00
2021-03-10 09:18:07 +00:00
[Header("Scene Links")]
2021-05-08 07:35:16 +01:00
public GameObject UiRoot ;
public GameObject HelpScreen ;
public InputDisplayLayout InputDisplayLayout ;
2021-04-18 05:13:20 +01:00
public Transform ActionBar ;
public ActionBarSlot ActionBarSlot ;
2021-03-27 10:03:24 +00:00
public Transform EffectManagerParent ;
2021-04-09 14:01:34 +01:00
public ZoneRenderer ZoneRenderer ;
2020-12-22 03:13:43 +00:00
public CinemachineVirtualCamera DockCamera ;
2020-11-29 22:50:12 +00:00
public CinemachineVirtualCamera FollowCamera ;
2021-03-27 10:03:24 +00:00
public CinemachineVirtualCamera WormholeCamera ;
2021-03-15 11:40:46 +00:00
//public SectorRenderer SectorRenderer;
public SectorMap SectorMap ;
2021-04-29 00:21:33 +01:00
[Header("Menu UI")]
public MainMenu MainMenu ;
public MenuPanel Menu ;
public MapRenderer MenuMap ;
public TradeMenu TradeMenu ;
2020-12-14 02:56:35 +00:00
public InventoryMenu Inventory ;
2020-12-27 22:18:22 +00:00
public InventoryPanel ShipPanel ;
2021-01-11 02:56:37 +00:00
public InventoryPanel TargetShipPanel ;
2021-03-27 10:03:24 +00:00
public ConfirmationDialog Dialog ;
2021-04-14 03:29:14 +01:00
public ContextMenu Context ;
public DropdownMenu Dropdown ;
2021-04-29 00:21:33 +01:00
[Header("Gameplay UI")]
public CanvasGroup GameplayUI ;
public EventLog EventLog ;
public Prototype HostileTargetIndicator ;
2021-05-11 04:45:42 +01:00
public Prototype FriendlyTargetIndicator ;
2021-04-29 00:21:33 +01:00
public PlaceUIElementWorldspace ViewDot ;
public Prototype LockIndicator ;
public PlaceUIElementWorldspace [ ] Crosshairs ;
public GameObject HitMarker ;
public float HitMarkerDuration ;
public SchematicDisplay SchematicDisplay ;
public SchematicDisplay TargetSchematicDisplay ;
[Header("Target Indicator")]
public PlaceUIElementWorldspace TargetIndicator ;
public Image TargetHitpointsFill ;
public Image TargetVisibilityFill ;
public Image VisibilityToTargetFill ;
public Image TargetShieldsBackground ;
public Image TargetShieldsFill ;
public Image TargetShieldsIcon ;
public Color ShieldColor ;
public Color NoShieldColor ;
public Sprite ShieldIcon ;
public Sprite NoShieldIcon ;
2021-03-27 10:03:24 +00:00
public float IntroDuration ;
2020-12-14 02:56:35 +00:00
2020-12-02 16:42:09 +00:00
//public PlayerInput Input;
2020-11-29 22:50:12 +00:00
2020-12-22 03:13:43 +00:00
// private CinemachineFramingTransposer _transposer;
// private CinemachineComposer _composer;
2021-01-18 02:35:56 +00:00
2021-04-09 14:01:34 +01:00
private bool _paused ;
2020-11-29 22:50:12 +00:00
private float _time ;
2020-12-02 16:42:09 +00:00
private int _zoomLevelIndex ;
2021-03-10 09:18:07 +00:00
private Entity _currentEntity ;
2021-01-14 23:47:08 +00:00
2021-01-05 02:56:17 +00:00
// private ShipInput _shipInput;
2021-03-10 09:18:07 +00:00
private float2 _entityYawPitch ;
2020-12-22 03:13:43 +00:00
private float3 _viewDirection ;
2021-01-18 02:35:56 +00:00
private ( HardpointData [ ] hardpoints , Transform [ ] barrels , PlaceUIElementWorldspace crosshair ) [ ] _articulationGroups ;
2021-01-25 05:53:36 +00:00
private ( LockWeapon targetLock , PlaceUIElementWorldspace indicator , Rotate spin ) [ ] _lockingIndicators ;
2021-05-11 04:45:42 +01:00
private Dictionary < Entity , VisibleTargetIndicator > _visibleHostileIndicators = new Dictionary < Entity , VisibleTargetIndicator > ( ) ;
private Dictionary < Entity , VisibleTargetIndicator > _visibleFriendlyIndicators = new Dictionary < Entity , VisibleTargetIndicator > ( ) ;
2021-03-06 02:42:19 +00:00
private List < IDisposable > _shipSubscriptions = new List < IDisposable > ( ) ;
2021-04-27 16:44:44 +01:00
private List < IDisposable > _targetSubscriptions = new List < IDisposable > ( ) ;
2021-03-06 02:42:19 +00:00
private float _severeHeatstrokePhase ;
2021-03-27 10:03:24 +00:00
private bool _uiHidden ;
2021-04-09 14:01:34 +01:00
private bool _menuShown ;
2021-04-18 05:13:20 +01:00
private List < ActionBarSlot > _actionBarSlots = new List < ActionBarSlot > ( ) ;
private List < InputAction > _actionBarActions = new List < InputAction > ( ) ;
2021-04-27 16:44:44 +01:00
private float _hitMarkerTime ;
2021-02-11 03:14:20 +00:00
2021-03-27 10:03:24 +00:00
public AetheriaInput Input { get ; private set ; }
2021-01-14 23:47:08 +00:00
public EquippedDockingBay DockingBay { get ; private set ; }
2021-02-01 08:13:14 +00:00
public Entity DockedEntity { get ; private set ; }
2021-06-06 16:54:01 +02:00
//if better place, please move
public Entity TowingStation { get ; private set ; }
2021-03-06 02:42:19 +00:00
2022-07-21 21:40:44 +01:00
public ZoneEnvironment CurrentEnvironment
{
get
{
return Settings . DefaultEnvironment ;
}
}
2021-03-10 09:18:07 +00:00
public Entity CurrentEntity
2021-03-06 02:42:19 +00:00
{
2021-03-10 09:18:07 +00:00
get = > _currentEntity ;
set = > _currentEntity = value ;
2021-03-06 02:42:19 +00:00
}
2021-03-15 11:40:46 +00:00
2020-12-12 03:42:58 +00:00
public ItemManager ItemManager { get ; private set ; }
2020-11-29 22:50:12 +00:00
public Zone Zone { get ; private set ; }
2021-02-11 03:14:20 +00:00
public List < EntityPack > Loadouts { get ; } = new List < EntityPack > ( ) ;
2020-11-27 22:47:33 +00:00
2021-01-08 12:44:10 +00:00
private readonly ( float2 direction , string name ) [ ] _directions = {
( float2 ( 0 , 1 ) , "Front" ) ,
( float2 ( 1 , 0 ) , "Right" ) ,
( float2 ( - 1 , 0 ) , "Left" ) ,
( float2 ( 0 , - 1 ) , "Rear" )
} ;
2020-12-19 02:37:13 +00:00
2021-04-21 01:49:07 +01:00
public DragObject DragObject { get ; private set ; }
private Func < DragObject , bool > _endDragCallback ;
2021-04-19 03:46:35 +01:00
2021-04-19 04:35:46 +01:00
private List < Story > _stories = new List < Story > ( ) ;
2021-03-20 04:20:17 +00:00
public EntitySettings NewEntitySettings
{
get = > MessagePackSerializer . Deserialize < EntitySettings > ( MessagePackSerializer . Serialize ( Settings . GameplaySettings . DefaultEntitySettings ) ) ;
}
2021-03-06 02:42:19 +00:00
2021-01-19 01:22:56 +00:00
public void SaveLoadout ( EntityPack pack )
2021-01-18 02:35:56 +00:00
{
2026-06-13 05:21:22 +01:00
Loadouts . RemoveAll ( loadout = > loadout . Name = = pack . Name ) ;
Loadouts . Add ( pack ) ;
Debug . LogWarning ( "Loadout persistence belongs to the Verse state spine. The Unity client keeps loadouts in memory until Aetheria.State is available as a runtime package." ) ;
2021-03-15 11:40:46 +00:00
}
2021-04-14 03:29:14 +01:00
private void OnApplicationQuit ( ) = > SaveState ( ) ;
2021-03-15 11:40:46 +00:00
public void SaveState ( )
{
2026-06-13 05:21:22 +01:00
if ( CurrentGalaxy ! = null )
2026-06-13 05:39:06 +01:00
Debug . LogWarning ( "Run persistence belongs to the Verse state spine. Legacy run serialization is disabled." ) ;
2021-01-18 02:35:56 +00:00
}
2021-04-09 14:01:34 +01:00
private void OnDisable ( )
{
Input . Dispose ( ) ;
2021-04-10 01:47:16 +01:00
ConsoleController . ClearCommands ( ) ;
EntityInstance . ClearWeaponManagers ( ) ;
2021-04-09 14:01:34 +01:00
}
2020-11-27 22:47:33 +00:00
void Start ( )
{
2021-04-12 04:20:52 +01:00
Instance = this ;
2021-03-27 10:03:24 +00:00
EntityInstance . EffectManagerParent = EffectManagerParent ;
2020-11-29 22:50:12 +00:00
ConsoleController . MessageReceiver = this ;
2021-03-07 01:10:31 +00:00
2026-06-13 01:59:17 +01:00
Debug . Log ( $"Aetheria typed state file: {AetheriaStateFilePath}" ) ;
Debug . Log ( $"Aetheria legacy item catalog: {LegacyAetherDatabasePath}" ) ;
ItemManager = new ItemManager ( LegacyCultCache , Settings . GameplaySettings , Debug . Log ) ;
2021-03-15 11:40:46 +00:00
ZoneRenderer . ItemManager = ItemManager ;
2022-07-18 08:44:54 +01:00
// If hiding minimap asteroids, turn them off to start with
if ( ! PlayerSettings . GraphicsSettings . ShowAsteroidsInMinimap )
ZoneRenderer . ShowAsteroidUI = false ;
2021-04-27 16:44:44 +01:00
// TODO: Process Stories
2021-04-19 04:35:46 +01:00
2021-03-09 02:26:58 +00:00
#region Input Handling
2020-11-29 22:50:12 +00:00
2021-03-27 10:03:24 +00:00
Input = new AetheriaInput ( ) ;
2021-05-08 07:35:16 +01:00
foreach ( var x in PlayerSettings . InputSettings . InputActionMap ) Input . asset [ x . Key . action ] . ApplyBindingOverride ( x . Key . binding , x . Value ) ;
InputDisplayLayout . Input = Input . asset ;
2021-03-27 10:03:24 +00:00
Input . Global . Enable ( ) ;
2020-12-02 16:42:09 +00:00
_zoomLevelIndex = Settings . DefaultMinimapZoom ;
2021-03-27 10:03:24 +00:00
Input . Player . MinimapZoom . performed + = context = >
2020-12-02 16:42:09 +00:00
{
_zoomLevelIndex = ( _zoomLevelIndex + 1 ) % Settings . MinimapZoomLevels . Length ;
2021-03-15 11:40:46 +00:00
ZoneRenderer . MinimapDistance = Settings . MinimapZoomLevels [ _zoomLevelIndex ] ;
2020-12-02 16:42:09 +00:00
} ;
2021-04-14 03:29:14 +01:00
Input . Global . ZoneMap . performed + = context = >
2020-12-18 13:48:03 +00:00
{
2021-04-14 03:29:14 +01:00
ToggleMenuTab ( MenuTab . Map ) ;
2025-01-30 01:58:05 +00:00
MenuMap . Position = CurrentEntity . Position . xz ;
2020-12-18 13:48:03 +00:00
} ;
2021-04-14 03:29:14 +01:00
Input . Global . Inventory . performed + = context = > ToggleMenuTab ( MenuTab . Inventory ) ;
2020-12-18 13:48:03 +00:00
2021-04-14 03:29:14 +01:00
Input . Global . GalaxyMap . performed + = context = > ToggleMenuTab ( MenuTab . Galaxy ) ;
2020-12-02 21:12:25 +00:00
2021-05-06 02:34:19 +01:00
Input . Global . Interact . performed + = context = >
2020-12-22 03:13:43 +00:00
{
2021-04-21 01:49:07 +01:00
if ( EventSystem . current . currentSelectedGameObject ! = null & & EventSystem . current . currentSelectedGameObject . GetComponent < TMP_InputField > ( ) ! = null ) return ;
2021-04-09 14:01:34 +01:00
if ( MainMenu . gameObject . activeSelf ) return ;
2021-03-10 09:18:07 +00:00
if ( CurrentEntity = = null )
2021-02-05 03:21:15 +00:00
{
2022-07-10 02:53:09 +01:00
// TODO: SFX: Fail
2021-03-15 11:40:46 +00:00
Dialog . Clear ( ) ;
Dialog . Title . text = "Can't undock. You dont have a ship!" ;
Dialog . Show ( ) ;
Dialog . MoveToCursor ( ) ;
2021-02-05 03:21:15 +00:00
}
2021-05-06 02:34:19 +01:00
else if ( CurrentEntity . Parent = = null )
{
foreach ( var wormhole in ZoneRenderer . WormholeInstances . Keys )
{
if ( ! ( length ( wormhole . Position - CurrentEntity . Position . xz ) < Settings . GameplaySettings . WormholeExitRadius ) ) continue ;
EnterWormhole ( wormhole ) ;
}
Dock ( ) ;
}
2020-12-22 03:13:43 +00:00
else Undock ( ) ;
} ;
2025-07-18 00:21:33 +01:00
Input . Global . MainMenu . performed + = context = >
{
if ( Menu . gameObject . activeSelf )
ToggleMenuTab ( Menu . CurrentTab ) ;
else
ToggleFullscreenMenu ( MainMenu . gameObject ) ;
} ;
2021-05-08 07:35:16 +01:00
Input . Global . InputScreen . performed + = context = > ToggleFullscreenMenu ( HelpScreen ) ;
2021-04-09 14:01:34 +01:00
2021-03-27 10:03:24 +00:00
Input . Player . HideUI . performed + = context = >
{
_uiHidden = ! _uiHidden ;
GameplayUI . alpha = _uiHidden ? 0 : 1 ;
2021-05-11 04:45:42 +01:00
ActionBar . gameObject . SetActive ( ! _uiHidden ) ;
2021-03-27 10:03:24 +00:00
} ;
Input . Player . OverrideShutdown . performed + = context = >
2021-03-07 01:10:31 +00:00
{
2021-03-10 09:18:07 +00:00
CurrentEntity . OverrideShutdown = ! CurrentEntity . OverrideShutdown ;
2021-03-07 01:10:31 +00:00
} ;
2021-03-27 10:03:24 +00:00
Input . Player . Ping . performed + = context = >
2021-03-21 01:55:25 +00:00
{
CurrentEntity . Sensor ? . Ping ( ) ;
} ;
2021-03-27 10:03:24 +00:00
Input . Player . ToggleHeatsinks . performed + = context = >
2021-03-04 03:58:46 +00:00
{
2021-03-10 09:18:07 +00:00
CurrentEntity . HeatsinksEnabled = ! CurrentEntity . HeatsinksEnabled ;
2022-07-10 02:53:09 +01:00
// TODO: SFX: Success/Fail
2021-03-04 03:58:46 +00:00
} ;
2021-03-27 10:03:24 +00:00
Input . Player . ToggleShield . performed + = context = >
2021-03-06 01:04:26 +00:00
{
2021-03-10 09:18:07 +00:00
if ( CurrentEntity . Shield ! = null )
2021-03-06 01:04:26 +00:00
{
2021-03-10 09:18:07 +00:00
CurrentEntity . Shield . Item . Enabled . Value = ! CurrentEntity . Shield . Item . Enabled . Value ;
2022-07-10 02:53:09 +01:00
// TODO: SFX: Success/Fail
2021-03-06 01:04:26 +00:00
}
} ;
2021-03-05 21:45:32 +00:00
#region Targeting
2021-03-27 10:03:24 +00:00
Input . Player . TargetReticle . performed + = context = >
2021-01-10 03:59:47 +00:00
{
2021-05-11 04:45:42 +01:00
if ( ! CurrentEntity . VisibleEnemies . Any ( ) ) return ;
var underReticle = CurrentEntity . VisibleEnemies . Where ( x = > x ! = CurrentEntity )
2021-03-10 09:18:07 +00:00
. MaxBy ( x = > dot ( normalize ( x . Position - CurrentEntity . Position ) , CurrentEntity . LookDirection ) ) ;
CurrentEntity . Target . Value = CurrentEntity . Target . Value = = underReticle ? null : underReticle ;
2021-01-10 03:59:47 +00:00
} ;
2021-03-27 10:03:24 +00:00
Input . Player . TargetNearest . performed + = context = >
2021-01-10 03:59:47 +00:00
{
2021-05-11 04:45:42 +01:00
if ( CurrentEntity . VisibleEnemies . Any ( ) )
2021-04-09 14:01:34 +01:00
{
2021-05-11 04:45:42 +01:00
CurrentEntity . Target . Value = CurrentEntity . VisibleEnemies . Where ( x = > x ! = CurrentEntity )
2021-04-09 14:01:34 +01:00
. MaxBy ( x = > length ( x . Position - CurrentEntity . Position ) ) ;
}
2021-01-10 03:59:47 +00:00
} ;
2021-03-27 10:03:24 +00:00
Input . Player . TargetNext . performed + = context = >
2021-01-10 03:59:47 +00:00
{
2021-05-11 04:45:42 +01:00
if ( ! CurrentEntity . VisibleEnemies . Any ( ) ) return ;
var targets = CurrentEntity . VisibleEnemies . Where ( x = > x ! = CurrentEntity ) . OrderBy ( x = > length ( x . Position - CurrentEntity . Position ) ) . ToArray ( ) ;
2021-03-10 09:18:07 +00:00
var currentTargetIndex = Array . IndexOf ( targets , CurrentEntity . Target . Value ) ;
CurrentEntity . Target . Value = targets [ ( currentTargetIndex + 1 ) % targets . Length ] ;
2021-01-10 03:59:47 +00:00
} ;
2021-03-27 10:03:24 +00:00
Input . Player . TargetPrevious . performed + = context = >
2021-01-10 03:59:47 +00:00
{
2021-05-11 04:45:42 +01:00
if ( ! CurrentEntity . VisibleEnemies . Any ( ) ) return ;
var targets = CurrentEntity . VisibleEnemies . Where ( x = > x ! = CurrentEntity ) . OrderBy ( x = > length ( x . Position - CurrentEntity . Position ) ) . ToArray ( ) ;
2021-03-10 09:18:07 +00:00
var currentTargetIndex = Array . IndexOf ( targets , CurrentEntity . Target . Value ) ;
CurrentEntity . Target . Value = targets [ ( currentTargetIndex + targets . Length - 1 ) % targets . Length ] ;
2021-01-10 03:59:47 +00:00
} ;
2021-03-05 21:45:32 +00:00
#endregion
2021-01-10 03:59:47 +00:00
2021-04-18 05:13:20 +01:00
#region Action Bar
2021-01-05 02:56:17 +00:00
2021-04-18 05:13:20 +01:00
ActionBarSlot createBinding ( string controlPath )
2021-01-05 02:56:17 +00:00
{
2021-04-18 05:13:20 +01:00
var action = new InputAction ( binding : controlPath ) ;
_actionBarActions . Add ( action ) ;
var slot = Instantiate ( ActionBarSlot , ActionBar ) ;
2021-04-19 03:46:35 +01:00
slot . Binding = null ;
2021-04-18 05:13:20 +01:00
_actionBarSlots . Add ( slot ) ;
action . started + = context = > slot . Binding ? . Activate ( ) ;
action . canceled + = context = > slot . Binding ? . Deactivate ( ) ;
2021-04-19 03:46:35 +01:00
2021-05-06 18:43:23 +01:00
var shortName = controlPath . Substring ( controlPath . LastIndexOf ( '/' ) + 1 ) ;
var sprite = Resources . Load < Sprite > ( $"Sprites/Input/{shortName}" ) ;
if ( sprite ! = null )
{
slot . InputIcon . sprite = sprite ;
slot . InputLabel . gameObject . SetActive ( false ) ;
}
else
{
slot . InputLabel . text = shortName ;
slot . InputIcon . gameObject . SetActive ( false ) ;
}
2021-04-19 03:46:35 +01:00
slot . PointerEnterTrigger . OnPointerEnterAsObservable ( ) . Subscribe ( _ = >
{
2025-07-18 00:21:33 +01:00
//Debug.Log($"Pointer entered action bar slot {controlPath}");
2021-04-19 03:46:35 +01:00
RegisterDragTarget ( dragAction = >
{
//Debug.Log("Registering binding!");
switch ( dragAction )
{
2021-04-21 01:49:07 +01:00
case EquippedItemDragObject equippedItemDragAction :
var trigger = equippedItemDragAction . EquippedItem . GetBehavior < IActivatedBehavior > ( ) ;
if ( trigger = = null ) return false ;
slot . Binding = new ActionBarGearBinding ( CurrentEntity , slot , equippedItemDragAction . EquippedItem , trigger ) ;
return true ;
case ItemInstanceDragObject itemInstanceDragAction :
if ( ! ( itemInstanceDragAction . Item . Data . Value is ConsumableItemData consumable ) ) return false ;
slot . Binding = new ActionBarConsumableBinding ( CurrentEntity , slot , consumable ) ;
return true ;
case WeaponGroupDragObject weaponGroupDragAction :
2021-04-19 03:46:35 +01:00
slot . Binding = new ActionBarWeaponGroupBinding ( CurrentEntity , slot , weaponGroupDragAction . Group ) ;
2021-04-21 01:49:07 +01:00
return true ;
2021-04-19 03:46:35 +01:00
default :
throw new ArgumentOutOfRangeException ( nameof ( dragAction ) ) ;
}
} ) ;
} ) ;
slot . PointerExitTrigger . OnPointerExitAsObservable ( ) . Subscribe ( _ = >
{
//Debug.Log($"Pointer exited action bar slot {controlPath}");
UnregisterDragTarget ( ) ;
} ) ;
2021-04-18 05:13:20 +01:00
return slot ;
}
2021-01-05 02:56:17 +00:00
2025-01-30 01:58:05 +00:00
var bindings = PlayerSettings . InputSettings . ActionBarInputs . OrderBy ( i = > i )
. Select ( createBinding ) . ToList ( ) ;
2021-01-05 02:56:17 +00:00
#endregion
2021-03-09 02:26:58 +00:00
#endregion
StartGame ( ) ;
2021-03-27 10:03:24 +00:00
2025-01-30 01:58:05 +00:00
//if (!PlayerSettings.InputSettings.ActionBarInputs.Any())
{
var newbinds = Enumerable . Range ( 0 , 64 ) //CurrentEntity.WeaponGroups
. Zip (
bindings ,
( i , slot ) = >
slot . Binding = new ActionBarWeaponGroupBinding ( CurrentEntity , slot , i )
) ;
}
2021-04-09 14:01:34 +01:00
ConsoleController . AddCommand ( "revealzones" ,
_ = >
{
2021-05-14 03:03:28 +01:00
foreach ( var zones in CurrentGalaxy . Zones
. Where ( z = > ! CurrentGalaxy . DiscoveredZones . Contains ( z ) )
. GroupBy ( z = > z . Distance [ CurrentGalaxy . Entrance ] )
2021-04-09 14:01:34 +01:00
. OrderBy ( g = > g . Key ) )
{
SectorMap . QueueZoneReveal ( zones ) ;
}
} ) ;
2021-03-27 10:03:24 +00:00
ConsoleController . AddCommand ( "give" ,
args = >
{
var itemName = string . Join ( " " , args ) ;
var item = ItemManager . ItemData . GetAll < EquippableItemData > ( )
. FirstOrDefault ( itemData = > string . Equals ( itemData . Name , itemName , StringComparison . InvariantCultureIgnoreCase ) ) ;
if ( item ! = null )
{
_currentEntity . CargoBays . First ( ) . TryStore ( ItemManager . CreateInstance ( item , . 95f ) ) ;
}
} ) ;
ConsoleController . AddCommand ( "trackmissile" ,
_ = >
{
2025-07-18 00:21:33 +01:00
foreach ( var missileManager in FindObjectsByType < GuidedProjectileManager > ( FindObjectsSortMode . None ) )
2021-03-27 10:03:24 +00:00
{
missileManager . OnFireGuided . Where ( x = > x . source = = _currentEntity ) . Take ( 1 ) . Subscribe ( x = >
{
FollowCamera . Follow = x . missile . transform ;
FollowCamera . LookAt = x . target ;
x . missile . OnKill + = ( ) = >
{
FollowCamera . LookAt = ZoneRenderer . EntityInstances [ CurrentEntity ] . LookAtPoint ;
FollowCamera . Follow = ZoneRenderer . EntityInstances [ CurrentEntity ] . transform ;
} ;
} ) ;
}
} ) ;
2021-04-15 04:25:22 +01:00
ConsoleController . AddCommand ( "spawnturret" ,
_ = >
{
2021-05-14 03:03:28 +01:00
var nearestFaction = CurrentGalaxy . Factions . MinBy ( f = > CurrentGalaxy . HomeZones [ f ] . Distance [ Zone . GalaxyZone ] ) ;
2021-04-15 04:25:22 +01:00
2021-04-22 02:53:06 +01:00
var loadoutGenerator = IsTutorial ? new LoadoutGenerator (
2021-04-15 04:25:22 +01:00
ref ItemManager . Random ,
ItemManager ,
2021-05-14 03:03:28 +01:00
CurrentGalaxy ,
Zone . GalaxyZone ,
2021-04-15 04:25:22 +01:00
nearestFaction ,
2021-04-22 02:53:06 +01:00
. 5f ) : new LoadoutGenerator (
ref ItemManager . Random ,
ItemManager ,
2022-08-08 22:43:55 +01:00
CurrentGalaxy ,
Zone . GalaxyZone ,
2021-04-22 02:53:06 +01:00
nearestFaction ,
2021-04-15 04:25:22 +01:00
. 5f ) ;
var turret = EntitySerializer . Unpack ( ItemManager , Zone , loadoutGenerator . GenerateTurretLoadout ( ) , true ) ;
turret . Position . xz = _currentEntity . Position . xz +
ItemManager . Random . NextFloat2Direction ( ) * ItemManager . Random . NextFloat ( 50 , 500 ) ;
turret . Zone = Zone ;
Zone . Entities . Add ( turret ) ;
turret . Activate ( ) ;
} ) ;
2021-06-06 16:54:01 +02:00
//Temporary, or not
ConsoleController . AddCommand ( "tow" , _ = > TowShip ( ) ) ;
2021-04-22 02:53:06 +01:00
// ConsoleController.AddCommand("pingscene",
// _ =>
// {
// var startTime = Time.time;
// Observable.EveryUpdate().TakeWhile(_ => Time.time - startTime < 5).Subscribe(
// _ => Debug.Log($"{(int) (Time.time - startTime)}"),
// () =>
// {
// var nearestFaction = CurrentSector.Factions.MinBy(f => CurrentSector.HomeZones[f].Distance[Zone.SectorZone]);
// var nearestFactionHomeZone = CurrentSector.HomeZones[nearestFaction];
// var factionPresence = nearestFaction.InfluenceDistance - nearestFactionHomeZone.Distance[Zone.SectorZone] + 1;
//
// var loadoutGenerator = new LoadoutGenerator(
// ref ItemManager.Random,
// ItemManager,
// CurrentSector,
// Zone.SectorZone,
// nearestFaction,
// .5f);
//
// for (int i = 0; i < 8; i++)
// {
// var ship = EntitySerializer.Unpack(ItemManager, Zone, loadoutGenerator.GenerateShipLoadout(), true);
// ship.Position.xz = _currentEntity.Position.xz +
// ItemManager.Random.NextFloat2Direction() * ItemManager.Random.NextFloat(50, 500);
// ship.Zone = Zone;
// Zone.Entities.Add(ship);
// ship.Activate();
// }
//
// for (int i = 0; i < 8; i++)
// {
// var turret = EntitySerializer.Unpack(ItemManager, Zone, loadoutGenerator.GenerateTurretLoadout(), true);
// turret.Position.xz = _currentEntity.Position.xz +
// ItemManager.Random.NextFloat2Direction() * ItemManager.Random.NextFloat(50, 500);
// turret.Zone = Zone;
// Zone.Entities.Add(turret);
// turret.Activate();
// }
// });
// });
2020-11-27 22:47:33 +00:00
}
2021-04-21 01:49:07 +01:00
public void BeginDrag ( DragObject dragObject )
2021-04-19 03:46:35 +01:00
{
2021-04-21 01:49:07 +01:00
this . DragObject = dragObject ;
2021-04-19 03:46:35 +01:00
}
2021-04-21 01:49:07 +01:00
public void RegisterDragTarget ( Func < DragObject , bool > onEndDrag )
2021-04-19 03:46:35 +01:00
{
_endDragCallback = onEndDrag ;
}
public void UnregisterDragTarget ( )
{
_endDragCallback = null ;
}
2021-04-21 01:49:07 +01:00
public bool EndDrag ( )
2021-04-19 03:46:35 +01:00
{
2021-04-21 01:49:07 +01:00
var success = _endDragCallback ? . Invoke ( DragObject ) ;
DragObject = null ;
return success ? ? false ;
2021-04-19 03:46:35 +01:00
}
2021-04-18 05:13:20 +01:00
public void EnablePlayerInput ( )
{
2021-05-06 02:34:19 +01:00
Cursor . lockState = CursorLockMode . Locked ;
2021-04-18 05:13:20 +01:00
Input . Player . Enable ( ) ;
foreach ( var a in _actionBarActions ) a . Enable ( ) ;
}
public void DisablePlayerInput ( )
{
2021-05-06 02:34:19 +01:00
Cursor . lockState = CursorLockMode . None ;
2021-04-18 05:13:20 +01:00
Input . Player . Disable ( ) ;
foreach ( var a in _actionBarActions ) a . Disable ( ) ;
}
2021-04-14 03:29:14 +01:00
private void EnterWormhole ( Wormhole wormhole )
{
2021-05-14 03:03:28 +01:00
if ( ! ( CurrentEntity is Ship ship ) | | ship . WormholeAnimationInProgress ) return ;
2021-04-14 03:29:14 +01:00
// var wormholeCameraFollow = new GameObject("Wormhole Camera Follow").transform;
// wormholeCameraFollow.position = new Vector3(wormhole.Position.x, -50, wormhole.Position.y);
// wormholeCameraFollow.rotation = Quaternion.LookRotation(Vector3.down, ship.LookDirection);
// WormholeCamera.enabled = true;
// WormholeCamera.Follow = wormholeCameraFollow;
// FollowCamera.enabled = false;
ship . EnterWormhole ( wormhole . Position ) ;
ship . OnEnteredWormhole + = ( ) = >
{
var oldZone = Zone ;
PopulateLevel ( wormhole . Target ) ;
foreach ( var zone in wormhole . Target . AdjacentZones )
2021-05-14 03:03:28 +01:00
CurrentGalaxy . DiscoveredZones . Add ( zone ) ;
2021-04-14 03:29:14 +01:00
SectorMap . QueueZoneReveal ( wormhole . Target . AdjacentZones ) ;
2021-05-14 03:03:28 +01:00
ship . ExitWormhole ( ZoneRenderer . WormholeInstances . Keys . First ( w = > w . Target = = oldZone . GalaxyZone ) . Position ,
2021-04-14 03:29:14 +01:00
Settings . GameplaySettings . WormholeExitVelocity * ItemManager . Random . NextFloat2Direction ( ) ) ;
CurrentEntity . Zone = Zone ;
SaveState ( ) ;
} ;
}
2021-05-14 03:03:28 +01:00
public void PopulateLevel ( GalaxyZone galaxyZone )
2021-03-10 09:18:07 +00:00
{
2021-05-14 03:03:28 +01:00
if ( galaxyZone = = null ) throw new ArgumentNullException ( nameof ( galaxyZone ) ) ;
2021-03-18 00:36:34 +00:00
2021-05-14 03:03:28 +01:00
if ( galaxyZone . Contents = = null )
2021-03-15 11:40:46 +00:00
{
2021-05-14 03:03:28 +01:00
galaxyZone . PackedContents ? ? = ZoneGenerator . GenerateZone (
2021-03-18 00:36:34 +00:00
ItemManager ,
Settings . ZoneSettings ,
2021-05-14 03:03:28 +01:00
CurrentGalaxy ,
galaxyZone ,
2021-04-22 02:53:06 +01:00
IsTutorial
2021-03-15 11:40:46 +00:00
) ;
2021-05-14 03:03:28 +01:00
galaxyZone . Contents = new Zone ( ItemManager , Settings . PlanetSettings , galaxyZone . PackedContents , galaxyZone , CurrentGalaxy ) ;
2021-03-15 11:40:46 +00:00
}
2021-05-14 03:03:28 +01:00
Zone = galaxyZone . Contents ;
2021-04-30 11:19:25 +01:00
PlayMusic ( MusicType . Overworld ) ;
2021-03-10 09:18:07 +00:00
Zone . Log = s = > Debug . Log ( $"Zone: {s}" ) ;
if ( CurrentEntity ! = null )
{
CurrentEntity . Deactivate ( ) ;
2021-03-18 00:36:34 +00:00
CurrentEntity . Zone . Entities . Remove ( CurrentEntity ) ;
2021-03-10 09:18:07 +00:00
CurrentEntity . Zone = Zone ;
Zone . Entities . Add ( CurrentEntity ) ;
CurrentEntity . Activate ( ) ;
}
2021-03-15 11:40:46 +00:00
ZoneRenderer . LoadZone ( Zone ) ;
2021-03-10 09:18:07 +00:00
if ( CurrentEntity ! = null )
{
2021-03-13 03:23:58 +00:00
UnbindEntity ( ) ;
2021-03-10 09:18:07 +00:00
BindToEntity ( CurrentEntity ) ;
}
}
2021-05-08 07:35:16 +01:00
private void ToggleFullscreenMenu ( GameObject menu )
2021-04-18 05:13:20 +01:00
{
2021-05-08 07:35:16 +01:00
if ( EventSystem . current ! = null & & EventSystem . current . currentSelectedGameObject ! = null & & EventSystem . current . currentSelectedGameObject . GetComponent < TMP_InputField > ( ) ! = null ) return ;
2021-04-18 05:13:20 +01:00
if ( CurrentEntity = = null ) return ;
2021-05-08 07:35:16 +01:00
if ( menu . activeSelf )
2021-04-18 05:13:20 +01:00
{
_paused = false ;
2021-05-08 07:35:16 +01:00
menu . SetActive ( false ) ;
UiRoot . SetActive ( true ) ;
if ( ! _menuShown )
2021-04-18 05:13:20 +01:00
{
EnablePlayerInput ( ) ;
2021-05-06 02:34:19 +01:00
UpdatePlayerPanel ( ) ;
UpdateTargetPanel ( CurrentEntity . Target . Value ) ;
2021-04-18 05:13:20 +01:00
}
}
else
{
_paused = true ;
2021-05-08 07:35:16 +01:00
menu . SetActive ( true ) ;
UiRoot . SetActive ( false ) ;
2021-04-18 05:13:20 +01:00
_menuShown = Menu . gameObject . activeSelf ;
2021-05-08 07:35:16 +01:00
if ( ! _menuShown ) DisablePlayerInput ( ) ;
2021-04-18 05:13:20 +01:00
}
}
2021-04-14 03:29:14 +01:00
private void ToggleMenuTab ( MenuTab tab )
{
2021-04-21 01:49:07 +01:00
if ( EventSystem . current . currentSelectedGameObject ! = null & & EventSystem . current . currentSelectedGameObject . GetComponent < TMP_InputField > ( ) ! = null ) return ;
2021-04-14 03:29:14 +01:00
if ( MainMenu . gameObject . activeSelf ) return ;
if ( Menu . gameObject . activeSelf & & Menu . CurrentTab = = tab )
{
Menu . gameObject . SetActive ( false ) ;
if ( CurrentEntity ! = null & & CurrentEntity . Parent = = null )
{
2021-04-18 05:13:20 +01:00
EnablePlayerInput ( ) ;
2021-05-06 02:34:19 +01:00
UpdatePlayerPanel ( ) ;
UpdateTargetPanel ( CurrentEntity . Target . Value ) ;
2021-04-14 03:29:14 +01:00
GameplayUI . gameObject . SetActive ( true ) ;
}
return ;
}
2021-04-18 05:13:20 +01:00
DisablePlayerInput ( ) ;
2021-04-14 03:29:14 +01:00
Menu . ShowTab ( tab ) ;
GameplayUI . gameObject . SetActive ( false ) ;
}
2021-03-09 02:26:58 +00:00
private void StartGame ( )
{
2021-05-14 03:03:28 +01:00
if ( CurrentGalaxy ! = null )
2021-03-15 11:40:46 +00:00
{
2026-06-13 05:21:22 +01:00
SectorMap . QueueZoneReveal ( CurrentGalaxy . Entrance . AdjacentZones . Prepend ( CurrentGalaxy . Entrance ) ) ;
PopulateLevel ( CurrentGalaxy . Entrance ) ;
var loadoutGenerator = new LoadoutGenerator ( ref ItemManager . Random , ItemManager , CurrentGalaxy , Zone . GalaxyZone , IsTutorial ? CurrentGalaxy . ResolveFaction ( Settings . TutorialGenerationSettings . ProtagonistFaction ) : null , 2 ) ;
var ship = EntitySerializer . Unpack (
ItemManager ,
Zone ,
loadoutGenerator . GenerateShipLoadout ( data = > string . IsNullOrEmpty ( Settings . StartingHullName ) | | data . Name = = Settings . StartingHullName ) ,
true ) ;
// EntitySerializer.Unpack(ItemManager, Zone, Loadouts.First(x => x.Name == StarterShipTemplate), true);
( ( Ship ) ship ) . IsPlayerShip = true ;
ship . Position = float3 . zero ;
ship . Zone = Zone ;
Zone . Entities . Add ( ship ) ;
ship . Activate ( ) ;
BindToEntity ( ship ) ;
2021-03-15 11:40:46 +00:00
}
2021-03-09 02:26:58 +00:00
}
2021-03-27 10:03:24 +00:00
private IEnumerator IntroCutscene ( Ship ship )
{
ZoneRenderer . PerspectiveEntity = ship ;
var entityPosition = ship . Position . xz ;
var followOrbit = Zone . Orbits . Keys . MinBy ( o = > lengthsq ( Zone . GetOrbitPosition ( o ) - entityPosition ) ) ;
var followPlanet = ZoneRenderer . Planets [ Zone . Planets . FirstOrDefault ( p = > p . Value . Orbit = = followOrbit ) . Key ] ;
DockCamera . Follow = followPlanet . Body . transform ;
var rootOrbit = followOrbit ;
while ( Zone . Orbits [ rootOrbit ] . Data . Parent ! = Guid . Empty )
rootOrbit = Zone . Orbits [ rootOrbit ] . Data . Parent ;
var rootPlanet = ZoneRenderer . Planets [ Zone . Planets . FirstOrDefault ( p = > p . Value . Orbit = = rootOrbit ) . Key ] ;
DockCamera . LookAt = rootPlanet . Body . transform ;
var shipVelocity = ship . GetBehavior < VelocityLimit > ( ) . Limit ;
var followOrbitPosition = Zone . GetOrbitPosition ( followOrbit ) ;
var shipDirection = normalize ( Zone . GetOrbitPosition ( rootOrbit ) - followOrbitPosition ) ;
ship . Position . xz = followOrbitPosition - shipDirection * shipVelocity * IntroDuration ;
var startTime = Time . time ;
while ( Time . time - startTime < IntroDuration )
{
ship . Direction = shipDirection ;
ship . Velocity = shipDirection * shipVelocity ;
yield return null ;
}
BindToEntity ( ship ) ;
}
2020-12-20 03:04:52 +00:00
public void Dock ( )
{
2021-03-10 09:18:07 +00:00
if ( CurrentEntity . Parent ! = null ) return ;
if ( CurrentEntity is Ship ship )
2020-12-20 03:04:52 +00:00
{
2021-03-10 09:18:07 +00:00
foreach ( var entity in Zone . Entities . ToArray ( ) )
2020-12-20 03:04:52 +00:00
{
2021-05-12 01:41:18 +01:00
if ( entity ! = CurrentEntity & & lengthsq ( entity . Position . xz - CurrentEntity . Position . xz ) <
2021-03-10 09:18:07 +00:00
Settings . GameplaySettings . DockingDistance * Settings . GameplaySettings . DockingDistance )
2020-12-20 03:04:52 +00:00
{
2021-03-10 09:18:07 +00:00
var bay = entity . TryDock ( ship ) ;
if ( bay ! = null )
{
2021-03-13 03:23:58 +00:00
UnbindEntity ( ) ;
DoDock ( entity , bay ) ;
2022-07-10 02:53:09 +01:00
// TODO: SFX: Docking
//AkSoundEngine.PostEvent("Dock", gameObject);
2021-03-10 09:18:07 +00:00
return ;
}
2020-12-20 03:04:52 +00:00
}
}
}
}
2021-03-13 03:23:58 +00:00
private void DoDock ( Entity entity , EquippedDockingBay dockingBay )
{
2021-04-10 01:47:16 +01:00
TradeMenu . Inventory = entity . CargoBays . First ( ) ;
2021-03-13 03:23:58 +00:00
DockedEntity = entity ;
2021-03-15 11:40:46 +00:00
ZoneRenderer . PerspectiveEntity = DockedEntity ;
2021-03-13 03:23:58 +00:00
DockingBay = dockingBay ;
DockCamera . enabled = true ;
FollowCamera . enabled = false ;
var orbital = ( OrbitalEntity ) entity ;
2021-03-15 11:40:46 +00:00
DockCamera . Follow = ZoneRenderer . EntityInstances [ orbital ] . transform ;
2021-03-13 03:23:58 +00:00
var parentOrbit = Zone . Orbits [ orbital . OrbitData ] . Data . Parent ;
2021-03-27 10:03:24 +00:00
var parentOrbitPlanet = Zone . Planets . FirstOrDefault ( p = > p . Value . Orbit = = parentOrbit ) . Key ;
if ( ZoneRenderer . Planets . ContainsKey ( parentOrbitPlanet ) )
DockCamera . LookAt = ZoneRenderer . Planets [ parentOrbitPlanet ] . Body . transform ;
else DockCamera . LookAt = ZoneRenderer . ZoneRoot ;
2021-06-18 12:32:03 +01:00
if ( entity is OrbitalEntity { CanTow : true } )
2021-06-06 16:54:01 +02:00
TowingStation = entity ;
2021-03-13 03:23:58 +00:00
Menu . ShowTab ( MenuTab . Inventory ) ;
}
2020-12-22 03:13:43 +00:00
public void Undock ( )
{
2021-03-10 09:18:07 +00:00
if ( CurrentEntity . Parent = = null ) return ;
if ( CurrentEntity is Ship ship )
2020-12-31 19:53:16 +00:00
{
2021-03-10 09:18:07 +00:00
if ( CurrentEntity . GetBehavior < Cockpit > ( ) = = null )
{
2021-03-15 11:40:46 +00:00
Dialog . Clear ( ) ;
Dialog . Title . text = "Can't undock. Missing cockpit component!" ;
Dialog . Show ( ) ;
Dialog . MoveToCursor ( ) ;
2022-07-10 02:53:09 +01:00
// TODO: SFX: Fail
2021-03-10 09:18:07 +00:00
}
2021-04-15 04:25:22 +01:00
else if ( CurrentEntity . GetBehavior < Thruster > ( ) = = null & & CurrentEntity . GetBehavior < AetherDrive > ( ) = = null )
2021-03-10 09:18:07 +00:00
{
2021-03-15 11:40:46 +00:00
Dialog . Clear ( ) ;
Dialog . Title . text = "Can't undock. Missing thruster component!" ;
Dialog . Show ( ) ;
Dialog . MoveToCursor ( ) ;
2022-07-10 02:53:09 +01:00
// TODO: SFX: Fail
2021-03-10 09:18:07 +00:00
}
else if ( CurrentEntity . GetBehavior < Reactor > ( ) = = null )
{
2021-03-15 11:40:46 +00:00
Dialog . Clear ( ) ;
Dialog . Title . text = "Can't undock. Missing reactor component!" ;
Dialog . Show ( ) ;
Dialog . MoveToCursor ( ) ;
2022-07-10 02:53:09 +01:00
// TODO: SFX: Fail
2021-03-10 09:18:07 +00:00
}
else if ( CurrentEntity . Parent . TryUndock ( ship ) )
{
BindToEntity ( ship ) ;
2022-07-10 02:53:09 +01:00
// TODO: SFX: Undock
2021-03-10 09:18:07 +00:00
}
else
{
2021-03-15 11:40:46 +00:00
Dialog . Title . text = "Can't undock. Must empty docking bay!" ;
Dialog . Show ( ) ;
Dialog . MoveToCursor ( ) ;
2022-07-10 02:53:09 +01:00
// TODO: SFX: Fail
2021-03-10 09:18:07 +00:00
}
2020-12-31 19:53:16 +00:00
}
2020-12-22 03:13:43 +00:00
}
2021-06-06 16:54:01 +02:00
public void TowShip ( )
{
if ( CurrentEntity . Parent ! = null ) return ;
if ( CurrentEntity is Ship ship )
{
if ( Zone . Equals ( TowingStation . Zone ) )
{
var distance = ( int ) length ( TowingStation . Position . xz - CurrentEntity . Position . xz ) ;
CurrentEntity . Position . xz = TowingStation . Position . xz ;
Dock ( ) ;
//Debug.Log($"${distance}");
//payment = distance * TowingZoneRate;
}
else
{
var distance = Zone . GalaxyZone . Distance [ TowingStation . Zone . GalaxyZone ] ;
PopulateLevel ( TowingStation . Zone . GalaxyZone ) ;
CurrentEntity . Zone = Zone ;
CurrentEntity . Position . xz = TowingStation . Position . xz ;
Dock ( ) ;
//Debug.Log($"${distance * 1000}");
//payment = distance * TowingGalaxyRate;
}
}
}
2021-03-13 03:23:58 +00:00
private void UnbindEntity ( )
2021-03-09 02:26:58 +00:00
{
2021-05-11 04:45:42 +01:00
foreach ( var indicator in _visibleHostileIndicators ) Destroy ( indicator . Value . gameObject ) ;
2021-03-09 02:26:58 +00:00
_visibleHostileIndicators . Clear ( ) ;
2021-05-11 04:45:42 +01:00
foreach ( var indicator in _visibleFriendlyIndicators ) Destroy ( indicator . Value . gameObject ) ;
_visibleFriendlyIndicators . Clear ( ) ;
2021-03-09 02:26:58 +00:00
if ( _lockingIndicators ! = null ) foreach ( var ( _ , indicator , _ ) in _lockingIndicators )
indicator . GetComponent < Prototype > ( ) . ReturnToPool ( ) ;
2021-04-18 05:13:20 +01:00
DisablePlayerInput ( ) ;
2021-03-09 02:26:58 +00:00
Cursor . lockState = CursorLockMode . None ;
2021-03-27 10:03:24 +00:00
GameplayUI . gameObject . SetActive ( false ) ;
2021-03-09 02:26:58 +00:00
foreach ( var subscription in _shipSubscriptions ) subscription . Dispose ( ) ;
_shipSubscriptions . Clear ( ) ;
}
2021-03-13 03:23:58 +00:00
private void BindToEntity ( Entity entity )
2021-03-09 02:26:58 +00:00
{
2021-03-15 11:40:46 +00:00
if ( ! ZoneRenderer . EntityInstances . ContainsKey ( entity ) )
2021-03-13 03:23:58 +00:00
{
Debug . LogError ( $"Attempted to bind to entity {entity.Name}, but SectorRenderer has no such instance!" ) ;
return ;
}
CurrentEntity = entity ;
2021-05-14 03:03:28 +01:00
DeathPost . weight = 0 ;
2021-03-15 11:40:46 +00:00
ZoneRenderer . PerspectiveEntity = CurrentEntity ;
2021-03-13 03:23:58 +00:00
2021-03-09 02:26:58 +00:00
Menu . gameObject . SetActive ( false ) ;
DockedEntity = null ;
DockingBay = null ;
DockCamera . enabled = false ;
FollowCamera . enabled = true ;
2021-03-21 01:55:25 +00:00
if ( length ( CurrentEntity . Direction ) > . 1f )
_viewDirection = float3 ( CurrentEntity . Direction . x , 0 , CurrentEntity . Direction . y ) ;
2021-03-09 02:26:58 +00:00
Cursor . lockState = CursorLockMode . Locked ;
2021-04-18 05:13:20 +01:00
EnablePlayerInput ( ) ;
2021-03-27 10:03:24 +00:00
GameplayUI . gameObject . SetActive ( true ) ;
2021-03-10 09:18:07 +00:00
ShipPanel . Display ( CurrentEntity , true ) ;
SchematicDisplay . ShowShip ( CurrentEntity ) ;
2021-03-05 21:45:32 +00:00
2021-03-15 11:40:46 +00:00
FollowCamera . LookAt = ZoneRenderer . EntityInstances [ CurrentEntity ] . LookAtPoint ;
FollowCamera . Follow = ZoneRenderer . EntityInstances [ CurrentEntity ] . transform ;
2021-03-10 09:18:07 +00:00
_articulationGroups = CurrentEntity . Equipment
2021-03-05 21:45:32 +00:00
. Where ( item = > item . Behaviors . Any ( x = > x . Data is WeaponData & & ! ( x . Data is LauncherData ) ) )
2021-03-15 11:40:46 +00:00
. GroupBy ( item = > ZoneRenderer . EntityInstances [ CurrentEntity ]
2021-03-10 09:18:07 +00:00
. GetBarrel ( CurrentEntity . Hardpoints [ item . Position . x , item . Position . y ] )
2021-03-05 21:45:32 +00:00
. GetComponentInParent < ArticulationPoint > ( ) ? . Group ? ? - 1 )
. Select ( ( group , index ) = > {
return (
2021-03-10 09:18:07 +00:00
group . Select ( item = > CurrentEntity . Hardpoints [ item . Position . x , item . Position . y ] ) . ToArray ( ) ,
2021-03-15 11:40:46 +00:00
group . Select ( item = > ZoneRenderer . EntityInstances [ CurrentEntity ] . GetBarrel ( CurrentEntity . Hardpoints [ item . Position . x , item . Position . y ] ) ) . ToArray ( ) ,
2021-03-05 21:45:32 +00:00
Crosshairs [ index ]
) ;
} ) . ToArray ( ) ;
foreach ( var crosshair in Crosshairs )
crosshair . gameObject . SetActive ( false ) ;
foreach ( var group in _articulationGroups )
group . crosshair . gameObject . SetActive ( true ) ;
2021-03-07 23:24:22 +00:00
2021-04-30 11:19:25 +01:00
_shipSubscriptions . Add ( CurrentEntity . TargetedByCount . Subscribe ( count = >
{
PlayMusic ( count > 0 ? MusicType . Combat : MusicType . Overworld ) ;
} ) ) ;
2021-03-10 09:18:07 +00:00
_shipSubscriptions . Add ( CurrentEntity . Target . Subscribe ( target = >
2021-03-07 23:24:22 +00:00
{
2021-04-27 16:44:44 +01:00
// Clear previous subscriptions related to currently targeted enemy
foreach ( var subscription in _targetSubscriptions )
subscription . Dispose ( ) ;
_targetSubscriptions . Clear ( ) ;
2021-05-06 02:34:19 +01:00
UpdateTargetPanel ( target ) ;
2021-03-07 23:24:22 +00:00
if ( target ! = null )
{
2021-04-29 00:21:33 +01:00
if ( target . Shield ! = null )
{
TargetShieldsBackground . color = new Color ( ShieldColor . r , ShieldColor . g , ShieldColor . b , . 4f ) ;
TargetShieldsIcon . color = ShieldColor ;
TargetShieldsIcon . sprite = ShieldIcon ;
}
else
{
TargetShieldsBackground . color = new Color ( NoShieldColor . r , NoShieldColor . g , NoShieldColor . b , . 4f ) ;
TargetShieldsIcon . color = NoShieldColor ;
TargetShieldsIcon . sprite = NoShieldIcon ;
}
2021-04-27 16:44:44 +01:00
// Subscribe to incoming hits from the player ship to display the hit marker
_targetSubscriptions . Add ( target . IncomingHit . Where ( e = > e = = CurrentEntity ) . Subscribe ( _ = >
{
HitMarker . SetActive ( true ) ;
_hitMarkerTime = HitMarkerDuration ;
} ) ) ;
2021-03-07 23:24:22 +00:00
}
} ) ) ;
2021-05-11 04:45:42 +01:00
foreach ( var hostile in CurrentEntity . VisibleEnemies )
2021-03-07 23:24:22 +00:00
{
2021-05-11 04:45:42 +01:00
var indicator = HostileTargetIndicator . Instantiate < VisibleTargetIndicator > ( ) ;
2021-03-10 09:18:07 +00:00
_visibleHostileIndicators . Add ( hostile , indicator ) ;
2021-03-07 23:24:22 +00:00
}
2021-04-10 01:47:16 +01:00
2021-05-11 04:45:42 +01:00
_shipSubscriptions . Add ( CurrentEntity . VisibleEnemies . ObserveAdd ( ) . Subscribe ( addEvent = >
2021-03-07 23:24:22 +00:00
{
2021-05-11 04:45:42 +01:00
var indicator = HostileTargetIndicator . Instantiate < VisibleTargetIndicator > ( ) ;
2021-03-07 23:24:22 +00:00
_visibleHostileIndicators . Add ( addEvent . Value , indicator ) ;
} ) ) ;
2021-04-10 01:47:16 +01:00
2021-05-11 04:45:42 +01:00
_shipSubscriptions . Add ( CurrentEntity . VisibleEnemies . ObserveRemove ( ) . Subscribe ( removeEvent = >
2021-03-07 23:24:22 +00:00
{
_visibleHostileIndicators [ removeEvent . Value ] . GetComponent < Prototype > ( ) . ReturnToPool ( ) ;
_visibleHostileIndicators . Remove ( removeEvent . Value ) ;
} ) ) ;
2021-05-11 04:45:42 +01:00
foreach ( var friendly in CurrentEntity . VisibleFriendlies )
{
var indicator = FriendlyTargetIndicator . Instantiate < VisibleTargetIndicator > ( ) ;
_visibleFriendlyIndicators . Add ( friendly , indicator ) ;
}
_shipSubscriptions . Add ( CurrentEntity . VisibleFriendlies . ObserveAdd ( ) . Subscribe ( addEvent = >
{
var indicator = FriendlyTargetIndicator . Instantiate < VisibleTargetIndicator > ( ) ;
_visibleFriendlyIndicators . Add ( addEvent . Value , indicator ) ;
} ) ) ;
_shipSubscriptions . Add ( CurrentEntity . VisibleFriendlies . ObserveRemove ( ) . Subscribe ( removeEvent = >
{
_visibleFriendlyIndicators [ removeEvent . Value ] . GetComponent < Prototype > ( ) . ReturnToPool ( ) ;
_visibleFriendlyIndicators . Remove ( removeEvent . Value ) ;
} ) ) ;
2021-03-09 02:26:58 +00:00
2021-04-14 03:29:14 +01:00
_shipSubscriptions . Add ( CurrentEntity . Death . Subscribe ( Die ) ) ;
2021-03-09 02:26:58 +00:00
2021-03-10 09:18:07 +00:00
_lockingIndicators = CurrentEntity . GetBehaviors < LockWeapon > ( )
2021-03-09 02:26:58 +00:00
. Select ( x = >
{
var i = LockIndicator . Instantiate < PlaceUIElementWorldspace > ( ) ;
return ( x , i , i . GetComponent < Rotate > ( ) ) ;
} ) . ToArray ( ) ;
2021-03-05 21:45:32 +00:00
}
2021-05-06 02:34:19 +01:00
private void UpdatePlayerPanel ( )
{
ShipPanel . Display ( CurrentEntity , true ) ;
SchematicDisplay . ShowShip ( CurrentEntity ) ;
}
private void UpdateTargetPanel ( Entity target )
{
TargetIndicator . gameObject . SetActive ( target ! = null ) ;
TargetShipPanel . gameObject . SetActive ( target ! = null ) ;
if ( target ! = null )
{
TargetShipPanel . Display ( target , true ) ;
TargetSchematicDisplay . ShowShip ( target , CurrentEntity ) ;
}
}
2021-04-14 03:29:14 +01:00
private void Die ( CauseOfDeath cause )
{
var deathTime = Time . time ;
UnbindEntity ( ) ;
CurrentEntity = null ;
MainMenu . gameObject . SetActive ( true ) ;
Menu . gameObject . SetActive ( false ) ;
2021-05-14 03:03:28 +01:00
CurrentGalaxy = null ;
2021-04-14 03:29:14 +01:00
SavePlayerSettings ( ) ;
Observable . EveryUpdate ( )
2021-05-14 03:03:28 +01:00
. Where ( _ = > Time . time - deathTime < DeathPostTransitionTime )
2021-04-14 03:29:14 +01:00
. Subscribe ( _ = >
{
2021-05-14 03:03:28 +01:00
var t = ( Time . time - deathTime ) / DeathPostTransitionTime ;
2021-04-14 03:29:14 +01:00
if ( cause = = CauseOfDeath . Heatstroke )
{
2021-05-14 03:03:28 +01:00
HeatstrokePost . weight = 1 - t ;
SevereHeatstrokePost . weight = 1 - t ;
2021-04-14 03:29:14 +01:00
}
else if ( cause = = CauseOfDeath . Hypothermia )
{
2021-05-14 03:03:28 +01:00
HypothermiaPost . weight = 1 - t ;
SevereHypothermiaPost . weight = 1 - t ;
2021-04-14 03:29:14 +01:00
}
2021-05-14 03:03:28 +01:00
DeathPost . weight = t ;
2021-04-14 03:29:14 +01:00
} ,
( ) = >
{
2021-05-14 03:03:28 +01:00
HeatstrokePost . weight = 0 ;
SevereHeatstrokePost . weight = 0 ;
HypothermiaPost . weight = 0 ;
SevereHypothermiaPost . weight = 0 ;
DeathPost . weight = 1 ;
2021-04-14 03:29:14 +01:00
} ) ;
}
2026-06-13 05:21:22 +01:00
public void SaveZone ( string name )
{
Debug . LogWarning ( "Zone persistence belongs to the Verse state spine. Legacy .zone serialization is disabled." ) ;
}
2020-12-01 00:16:11 +00:00
2020-12-22 03:13:43 +00:00
// public void ToggleEditMode()
// {
// _editMode = !_editMode;
// FollowCamera.gameObject.SetActive(!_editMode);
// TopDownCamera.gameObject.SetActive(_editMode);
// }
2020-12-19 02:37:13 +00:00
public IEnumerable < EquippedCargoBay > AvailableCargoBays ( )
{
2021-03-10 09:18:07 +00:00
if ( CurrentEntity . Parent ! = null )
2020-12-19 02:37:13 +00:00
{
2021-03-10 09:18:07 +00:00
foreach ( var bay in CurrentEntity . Parent . DockingBays )
2020-12-19 02:37:13 +00:00
{
2021-03-15 11:40:46 +00:00
if ( bay . DockedShip . IsPlayerShip ) yield return bay ;
2020-12-19 02:37:13 +00:00
}
}
}
2021-02-11 03:14:20 +00:00
public IEnumerable < Entity > AvailableEntities ( )
2020-12-19 02:37:13 +00:00
{
2021-02-11 03:14:20 +00:00
if ( DockedEntity ! = null )
2021-03-15 11:40:46 +00:00
foreach ( var entity in DockedEntity . Children )
2020-12-19 02:37:13 +00:00
{
2021-03-15 11:40:46 +00:00
if ( entity is Ship { IsPlayerShip : true } ) yield return entity ;
2020-12-19 02:37:13 +00:00
}
2021-03-10 09:18:07 +00:00
else if ( CurrentEntity ! = null )
yield return CurrentEntity ;
2020-12-19 02:37:13 +00:00
}
2020-11-27 22:47:33 +00:00
2021-04-30 11:19:25 +01:00
public void PlayMusic ( MusicType type )
{
2022-07-10 02:53:09 +01:00
// TODO: SFX: Music
2021-04-30 11:19:25 +01:00
}
2020-11-29 22:50:12 +00:00
void Update ( )
2020-11-27 22:47:33 +00:00
{
2021-04-09 14:01:34 +01:00
if ( ! _paused )
2020-11-29 22:50:12 +00:00
{
_time + = Time . deltaTime ;
2021-04-27 16:44:44 +01:00
_hitMarkerTime - = Time . deltaTime ;
if ( HitMarker . activeSelf & & _hitMarkerTime < 0 ) HitMarker . SetActive ( false ) ;
2021-04-09 14:01:34 +01:00
// ItemManager.Time = _time;
2021-03-10 09:18:07 +00:00
if ( CurrentEntity ! = null & & CurrentEntity . Parent = = null )
2020-12-22 03:13:43 +00:00
{
2021-03-07 23:24:22 +00:00
foreach ( var indicator in _visibleHostileIndicators )
{
2021-03-10 09:18:07 +00:00
indicator . Value . gameObject . SetActive ( indicator . Key ! = CurrentEntity . Target . Value ) ;
2021-03-07 23:24:22 +00:00
indicator . Value . Place . Target = indicator . Key . Position ;
2021-04-12 04:20:52 +01:00
if ( ! indicator . Key . Active )
indicator . Value . Fill . enabled = false ;
else
{
indicator . Value . Fill . fillAmount =
saturate ( indicator . Key . EntityInfoGathered [ CurrentEntity ] / Settings . GameplaySettings . TargetDetectionInfoThreshold ) ;
indicator . Value . Fill . enabled =
! ( indicator . Key . EntityInfoGathered [ CurrentEntity ] > Settings . GameplaySettings . TargetDetectionInfoThreshold ) | |
sin ( TargetSpottedBlinkFrequency * Time . time ) + TargetSpottedBlinkOffset > 0 ;
}
2021-03-07 23:24:22 +00:00
}
2021-05-11 04:45:42 +01:00
foreach ( var indicator in _visibleFriendlyIndicators )
{
indicator . Value . gameObject . SetActive ( indicator . Key ! = CurrentEntity . Target . Value ) ;
indicator . Value . Place . Target = indicator . Key . Position ;
if ( ! indicator . Key . Active )
indicator . Value . Fill . enabled = false ;
else
{
indicator . Value . Fill . enabled = true ;
indicator . Value . Fill . fillAmount =
saturate ( indicator . Key . EntityInfoGathered [ CurrentEntity ] / Settings . GameplaySettings . TargetDetectionInfoThreshold ) ;
}
}
2021-03-27 10:03:24 +00:00
var look = Input . Player . Look . ReadValue < Vector2 > ( ) ;
2021-03-10 09:18:07 +00:00
_entityYawPitch = float2 ( _entityYawPitch . x + look . x * Sensitivity . x , clamp ( _entityYawPitch . y + look . y * Sensitivity . y , - . 45f * PI , . 45f * PI ) ) ;
_viewDirection = mul ( float3 ( 0 , 0 , 1 ) , Unity . Mathematics . float3x3 . Euler ( float3 ( _entityYawPitch . yx , 0 ) , RotationOrder . YXZ ) ) ;
CurrentEntity . LookDirection = _viewDirection ;
2021-05-14 03:03:28 +01:00
HeatstrokePost . weight = saturate ( unlerp ( 0 , Settings . GameplaySettings . SevereHeatstrokeRiskThreshold , CurrentEntity . Heatstroke ) ) ;
2021-03-10 09:18:07 +00:00
var severeHeatstrokeLerp = saturate ( unlerp ( Settings . GameplaySettings . SevereHeatstrokeRiskThreshold , 1 , CurrentEntity . Heatstroke ) ) ;
2021-05-14 03:03:28 +01:00
SevereHeatstrokePost . weight =
2021-03-06 02:42:19 +00:00
severeHeatstrokeLerp + severeHeatstrokeLerp * ( 1 - severeHeatstrokeLerp ) *
max ( Settings . HeatstrokePhasingFloor , sin ( Time . time * Settings . HeatstrokePhasingFrequency ) ) ;
2021-03-10 09:18:07 +00:00
if ( CurrentEntity is Ship ship )
{
2021-03-27 10:03:24 +00:00
ship . MovementDirection = Input . Player . Move . ReadValue < Vector2 > ( ) ;
2021-03-10 09:18:07 +00:00
}
2021-04-15 04:25:22 +01:00
2021-04-27 16:44:44 +01:00
var target = CurrentEntity . Target . Value ;
if ( target ! = null )
{
var threshold = Settings . GameplaySettings . TargetDetectionInfoThreshold ;
TargetVisibilityFill . fillAmount = lerp ( . 25f , . 75f , ( CurrentEntity . EntityInfoGathered [ target ] - threshold ) / ( 1 - threshold ) ) ;
VisibilityToTargetFill . fillAmount = lerp ( . 25f , . 75f , target . EntityInfoGathered [ CurrentEntity ] / threshold ) ;
TargetHitpointsFill . fillAmount = lerp ( . 25f , . 75f , target . Hull . Durability / target . EquippedHull . Data . Durability ) ;
2021-04-29 00:21:33 +01:00
TargetShieldsFill . fillAmount = target . Shield = = null ? 0 : lerp ( . 25f , . 75f , target . Shield . Progress ) ;
2021-04-27 16:44:44 +01:00
}
2021-04-15 04:25:22 +01:00
var tractorPower = Input . Player . TractorBeam . ReadValue < float > ( ) ;
CurrentEntity . TractorPower =
saturate ( CurrentEntity . TractorPower + sign ( tractorPower - CurrentEntity . TractorPower ) * Time . deltaTime * 2 ) ;
2020-12-22 03:13:43 +00:00
}
2021-04-09 14:01:34 +01:00
Zone . Update ( Time . deltaTime ) ;
2020-11-29 22:50:12 +00:00
}
2020-11-27 22:47:33 +00:00
}
2021-01-10 03:59:47 +00:00
private void LateUpdate ( )
{
UpdateTargetIndicators ( ) ;
}
private void UpdateTargetIndicators ( )
{
2021-03-10 09:18:07 +00:00
if ( CurrentEntity = = null | | CurrentEntity . Parent ! = null ) return ;
2021-01-10 03:59:47 +00:00
2021-03-15 11:40:46 +00:00
ViewDot . Target = ZoneRenderer . EntityInstances [ CurrentEntity ] . LookAtPoint . position ;
2021-03-10 09:18:07 +00:00
if ( CurrentEntity . Target . Value ! = null )
TargetIndicator . Target = CurrentEntity . Target . Value . Position ;
var distance = length ( ( float3 ) ViewDot . Target - CurrentEntity . Position ) ;
2021-01-18 02:35:56 +00:00
foreach ( var ( _ , barrels , crosshair ) in _articulationGroups )
2021-01-10 03:59:47 +00:00
{
var averagePosition = Vector3 . zero ;
foreach ( var barrel in barrels )
averagePosition + = barrel . position + barrel . forward * distance ;
averagePosition / = barrels . Length ;
crosshair . Target = averagePosition ;
}
2021-03-10 09:18:07 +00:00
2021-01-18 02:35:56 +00:00
foreach ( var ( targetLock , indicator , spin ) in _lockingIndicators )
2021-01-10 03:59:47 +00:00
{
2021-03-10 09:18:07 +00:00
var showLockingIndicator = targetLock . Lock > . 01f & & CurrentEntity . Target . Value ! = null & & CurrentEntity . Target . Value . IsHostileTo ( CurrentEntity ) ;
2021-01-10 03:59:47 +00:00
indicator . gameObject . SetActive ( showLockingIndicator ) ;
if ( showLockingIndicator )
2021-01-27 00:05:30 +00:00
{
2021-03-10 09:18:07 +00:00
indicator . Target = CurrentEntity . Target . Value . Position ;
2021-01-27 00:05:30 +00:00
indicator . NoiseAmplitude = Settings . GameplaySettings . LockIndicatorNoiseAmplitude * ( 1 - targetLock . Lock ) ;
indicator . NoiseFrequency = Settings . GameplaySettings . LockIndicatorFrequency . Evaluate ( targetLock . Lock ) ;
spin . Speed = Settings . GameplaySettings . LockSpinSpeed . Evaluate ( targetLock . Lock ) ;
}
2021-01-10 03:59:47 +00:00
}
}
2021-04-19 03:46:35 +01:00
}
2021-04-21 01:49:07 +01:00
public abstract class DragObject { }
2021-04-19 03:46:35 +01:00
2021-04-21 01:49:07 +01:00
public class WeaponGroupDragObject : DragObject
2021-04-19 03:46:35 +01:00
{
2021-04-21 01:49:07 +01:00
public WeaponGroupDragObject ( int group )
2021-04-19 03:46:35 +01:00
{
Group = group ;
}
public int Group { get ; }
}
2021-04-21 01:49:07 +01:00
public abstract class ItemDragObject : DragObject
2021-04-19 03:46:35 +01:00
{
2021-04-21 01:49:07 +01:00
protected ItemDragObject ( int2 originCellOffset , ItemInstance item )
2021-04-19 03:46:35 +01:00
{
2021-04-21 01:49:07 +01:00
OriginCellOffset = originCellOffset ;
2021-04-19 03:46:35 +01:00
Item = item ;
}
public ItemInstance Item { get ; }
2021-04-21 01:49:07 +01:00
public int2 OriginCellOffset { get ; }
2021-04-19 03:46:35 +01:00
}
2021-04-21 01:49:07 +01:00
public class ItemInstanceDragObject : ItemDragObject
2021-04-19 03:46:35 +01:00
{
2021-04-21 01:49:07 +01:00
public ItemInstanceDragObject ( ItemInstance item , EquippedCargoBay originInventory , int2 originCellOffset ) : base ( originCellOffset , item )
2021-04-19 03:46:35 +01:00
{
2021-04-21 01:49:07 +01:00
OriginInventory = originInventory ;
}
public EquippedCargoBay OriginInventory { get ; }
}
public class EquippedItemDragObject : ItemDragObject
{
public EquippedItemDragObject ( EquippedItem item , Entity originEntity , int2 originCellOffset ) : base ( originCellOffset , item . EquippableItem )
{
EquippedItem = item ;
OriginEntity = originEntity ;
2021-04-19 03:46:35 +01:00
}
2021-04-21 01:49:07 +01:00
public EquippedItem EquippedItem { get ; }
public Entity OriginEntity { get ; }
2025-01-30 01:58:05 +00:00
}