Species Component (#130)
* Fix this fug oksure Creates the initial species component, damage states, and threshold templates and hooks them into the damageable component * More rebase fixes * test * Pre future rebase * Please * Lol * Lol2 * SHADERS * Update Engine * yml file * Fix an initialization issue, injects dependencies * Fix error in loading shaders * Makes a master character ui controller component added upon client attachment to entity and remove upon client detachment from entity * Fixes just about everytrhing * Address PJB's comments * geeze * Make overlays work in worldspace instead of screen space and not cover user interfaces * update submodule
@@ -72,8 +72,12 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="EntryPoint.cs" />
|
||||
<Compile Include="GameObjects\Components\Actor\CharacterInterface.cs" />
|
||||
<Compile Include="GameObjects\Components\DamageableComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\HUD\Inventory\ClientInventoryComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Mobs\ICharacterUI.cs" />
|
||||
<Compile Include="GameObjects\Components\Mobs\SpeciesUI.cs" />
|
||||
<Compile Include="GameObjects\Components\Clothing\ClothingComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Inventory\ClientInventoryComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Items\ItemComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Power\ApcBoundUserInterface.cs" />
|
||||
<Compile Include="GameObjects\Components\Power\PowerCellVisualizer2D.cs" />
|
||||
@@ -81,6 +85,8 @@
|
||||
<Compile Include="GameObjects\EntitySystems\ClientNotifySystem.cs" />
|
||||
<Compile Include="GameObjects\EntitySystems\VerbSystem.cs" />
|
||||
<Compile Include="GameTicking\ClientGameTicker.cs" />
|
||||
<Compile Include="Graphics\Overlays\CircleMaskOverlay.cs" />
|
||||
<Compile Include="Graphics\Overlays\GradientCircleMask.cs" />
|
||||
<Compile Include="Input\ContentContexts.cs" />
|
||||
<Compile Include="Interfaces\IClientGameTicker.cs" />
|
||||
<Compile Include="Interfaces\IClientNotifyManager.cs" />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Client.GameObjects;
|
||||
using Content.Client.GameObjects.Components.Actor;
|
||||
using Content.Client.GameObjects.Components.Clothing;
|
||||
using Content.Client.GameObjects.Components.Construction;
|
||||
using Content.Client.GameObjects.Components.Power;
|
||||
@@ -15,11 +16,13 @@ using SS14.Client;
|
||||
using SS14.Client.Interfaces;
|
||||
using SS14.Client.Interfaces.Graphics.Overlays;
|
||||
using SS14.Client.Interfaces.Input;
|
||||
using SS14.Client.Player;
|
||||
using SS14.Client.Utility;
|
||||
using SS14.Shared.ContentPack;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Prototypes;
|
||||
using System;
|
||||
|
||||
namespace Content.Client
|
||||
{
|
||||
@@ -34,7 +37,6 @@ namespace Content.Client
|
||||
var prototypes = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
factory.RegisterIgnore("Interactable");
|
||||
factory.RegisterIgnore("Damageable");
|
||||
factory.RegisterIgnore("Destructible");
|
||||
factory.RegisterIgnore("Temperature");
|
||||
factory.RegisterIgnore("PowerTransfer");
|
||||
@@ -68,15 +70,22 @@ namespace Content.Client
|
||||
factory.Register<ConstructorComponent>();
|
||||
factory.Register<ConstructionGhostComponent>();
|
||||
factory.Register<IconSmoothComponent>();
|
||||
factory.Register<DamageableComponent>();
|
||||
factory.Register<ClothingComponent>();
|
||||
factory.Register<ItemComponent>();
|
||||
|
||||
factory.RegisterReference<ClothingComponent, ItemComponent>();
|
||||
|
||||
factory.Register<SpeciesUI>();
|
||||
factory.Register<CharacterInterface>();
|
||||
|
||||
factory.RegisterIgnore("Construction");
|
||||
factory.RegisterIgnore("Apc");
|
||||
factory.RegisterIgnore("Door");
|
||||
factory.RegisterIgnore("PoweredLight");
|
||||
factory.RegisterIgnore("Smes");
|
||||
factory.RegisterIgnore("Powercell");
|
||||
factory.RegisterIgnore("HandheldLight");
|
||||
|
||||
prototypes.RegisterIgnore("material");
|
||||
|
||||
@@ -87,6 +96,43 @@ namespace Content.Client
|
||||
IoCManager.BuildGraph();
|
||||
|
||||
IoCManager.Resolve<IParallaxManager>().LoadParallax();
|
||||
IoCManager.Resolve<IBaseClient>().PlayerJoinedServer += SubscribePlayerAttachmentEvents;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe events to the player manager after the player manager is set up
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void SubscribePlayerAttachmentEvents(object sender, EventArgs args)
|
||||
{
|
||||
IoCManager.Resolve<IPlayerManager>().LocalPlayer.EntityAttached += AttachPlayerToEntity;
|
||||
IoCManager.Resolve<IPlayerManager>().LocalPlayer.EntityDetached += DetachPlayerFromEntity;
|
||||
AttachPlayerToEntity(IoCManager.Resolve<IPlayerManager>().LocalPlayer, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the character interface master which combines all character interfaces into one window
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void AttachPlayerToEntity(object sender, EventArgs args)
|
||||
{
|
||||
var localplayer = (LocalPlayer)sender;
|
||||
|
||||
localplayer.ControlledEntity?.AddComponent<CharacterInterface>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the character interface master from this entity now that we have detached ourselves from it
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void DetachPlayerFromEntity(object sender, EventArgs args)
|
||||
{
|
||||
var localplayer = (LocalPlayer)sender;
|
||||
//Wont work atm, controlled entity gets nulled before this event fires
|
||||
localplayer.ControlledEntity?.RemoveComponent<CharacterInterface>();
|
||||
}
|
||||
|
||||
public override void PostInit()
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
using Content.Client.GameObjects.Components.Mobs;
|
||||
using Content.Shared.Input;
|
||||
using SS14.Client.Interfaces.Input;
|
||||
using SS14.Client.UserInterface.CustomControls;
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Input;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Utility;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Actor
|
||||
{
|
||||
/// <summary>
|
||||
/// A semi-abstract component which gets added to entities upon attachment and collects all character
|
||||
/// user interfaces into a single window and keybind for the user
|
||||
/// </summary>
|
||||
public class CharacterInterface : Component
|
||||
{
|
||||
public override string Name => "Character Interface Component";
|
||||
|
||||
/// <summary>
|
||||
/// Stored keybind to open the menu on keypress
|
||||
/// </summary>
|
||||
private InputCmdHandler _openMenuCmdHandler;
|
||||
|
||||
/// <summary>
|
||||
/// Window to hold each of the character interfaces
|
||||
/// </summary>
|
||||
private SS14Window _window;
|
||||
|
||||
/// <summary>
|
||||
/// Create the window with all character UIs and bind it to a keypress
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
//Use all the character ui interfaced components to create the character window
|
||||
var UIcomponents = Owner.GetAllComponents<ICharacterUI>();
|
||||
_window = new CharacterWindow(UIcomponents);
|
||||
|
||||
//Add to screen the window and hide it
|
||||
_window.AddToScreen();
|
||||
_window.Close();
|
||||
|
||||
//Toggle window visible/invisible on keypress
|
||||
_openMenuCmdHandler = InputCmdHandler.FromDelegate(session => {
|
||||
if (_window.Visible)
|
||||
{
|
||||
_window.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
_window.Open();
|
||||
}
|
||||
});
|
||||
|
||||
//Set keybind to open character menu
|
||||
var inputMgr = IoCManager.Resolve<IInputManager>();
|
||||
inputMgr.SetInputCommand(ContentKeyFunctions.OpenCharacterMenu, _openMenuCmdHandler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of window and the keypress binding
|
||||
/// </summary>
|
||||
public override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
|
||||
_window.Dispose();
|
||||
_window = null;
|
||||
|
||||
var inputMgr = IoCManager.Resolve<IInputManager>();
|
||||
inputMgr.SetInputCommand(ContentKeyFunctions.OpenCharacterMenu, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A window that collects and shows all the individual character user interfaces
|
||||
/// </summary>
|
||||
public class CharacterWindow : SS14Window
|
||||
{
|
||||
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Mobs/CharacterWindow.tscn");
|
||||
|
||||
public CharacterWindow(IEnumerable<ICharacterUI> windowcomponents)
|
||||
{
|
||||
//TODO: sort window components by priority of window component
|
||||
foreach(var element in windowcomponents.OrderByDescending(x => x.Priority))
|
||||
{
|
||||
Contents.AddChild(element.Scene);
|
||||
}
|
||||
|
||||
HideOnClose = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines ordering of the character user interface, small values come sooner
|
||||
/// </summary>
|
||||
public enum UIPriority
|
||||
{
|
||||
First = 0,
|
||||
Species = 100,
|
||||
Inventory = 200,
|
||||
Last = 99999
|
||||
}
|
||||
}
|
||||
31
Content.Client/GameObjects/Components/DamageableComponent.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Content.Shared.GameObjects;
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.Network;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Content.Client.GameObjects
|
||||
{
|
||||
/// <summary>
|
||||
/// Fuck I really hate doing this
|
||||
/// TODO: make sure the client only gets damageable component on the clientside entity for its player mob
|
||||
/// </summary>
|
||||
public class DamageableComponent : SharedDamageableComponent
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Damageable";
|
||||
|
||||
public Dictionary<DamageType, int> CurrentDamage = new Dictionary<DamageType, int>();
|
||||
|
||||
public override void HandleComponentState(ComponentState state)
|
||||
{
|
||||
base.HandleComponentState(state);
|
||||
|
||||
if(state is DamageComponentState)
|
||||
{
|
||||
var damagestate = (DamageComponentState)state;
|
||||
CurrentDamage = damagestate.CurrentDamage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,9 @@
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.Input;
|
||||
using SS14.Client.GameObjects;
|
||||
using SS14.Client.Interfaces.GameObjects.Components;
|
||||
using SS14.Client.Interfaces.Input;
|
||||
using SS14.Client.UserInterface;
|
||||
using SS14.Client.UserInterface.Controls;
|
||||
using SS14.Client.UserInterface.CustomControls;
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Input;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.Network;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Serialization;
|
||||
using SS14.Shared.Utility;
|
||||
@@ -20,21 +14,36 @@ using Content.Client.GameObjects.Components.Clothing;
|
||||
using SS14.Shared.Interfaces.Reflection;
|
||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
||||
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
|
||||
using Content.Client.GameObjects.Components.Mobs;
|
||||
using Content.Client.GameObjects.Components.Actor;
|
||||
|
||||
namespace Content.Client.GameObjects
|
||||
{
|
||||
public class ClientInventoryComponent : SharedInventoryComponent
|
||||
/// <summary>
|
||||
/// A character UI which shows items the user has equipped within his inventory
|
||||
/// </summary>
|
||||
public class ClientInventoryComponent : SharedInventoryComponent, ICharacterUI
|
||||
{
|
||||
private Dictionary<Slots, IEntity> _slots = new Dictionary<Slots, IEntity>();
|
||||
|
||||
/// <summary>
|
||||
/// Holds the godot control for the inventory window
|
||||
/// </summary>
|
||||
private InventoryWindow _window;
|
||||
|
||||
private string _templateName = "HumanInventory"; //stored for serialization purposes
|
||||
|
||||
private InputCmdHandler _openMenuCmdHandler;
|
||||
/// <summary>
|
||||
/// Inventory template after being loaded from instance creator and string name
|
||||
/// </summary>
|
||||
private Inventory _inventory;
|
||||
|
||||
private ISpriteComponent _sprite;
|
||||
|
||||
//Relevant interface implementation for the character UI controller
|
||||
public Control Scene => _window;
|
||||
public UIPriority Priority => UIPriority.Inventory;
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
@@ -42,22 +51,17 @@ namespace Content.Client.GameObjects
|
||||
_window.Dispose();
|
||||
}
|
||||
|
||||
public override void OnAdd()
|
||||
{
|
||||
base.OnAdd();
|
||||
|
||||
_openMenuCmdHandler = InputCmdHandler.FromDelegate(session => { _window.AddToScreen(); _window.Open(); });
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
//Loads inventory template
|
||||
var reflectionManager = IoCManager.Resolve<IReflectionManager>();
|
||||
var type = reflectionManager.LooseGetType(_templateName);
|
||||
DebugTools.Assert(type != null);
|
||||
_inventory = (Inventory)Activator.CreateInstance(type);
|
||||
|
||||
//Creates godot control class for inventory
|
||||
_window = new InventoryWindow(this);
|
||||
_window.CreateInventory(_inventory);
|
||||
|
||||
@@ -120,21 +124,6 @@ namespace Content.Client.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||
{
|
||||
var inputMgr = IoCManager.Resolve<IInputManager>();
|
||||
switch (message)
|
||||
{
|
||||
case PlayerAttachedMsg _:
|
||||
inputMgr.SetInputCommand(ContentKeyFunctions.OpenCharacterMenu, _openMenuCmdHandler);
|
||||
break;
|
||||
|
||||
case PlayerDetachedMsg _:
|
||||
inputMgr.SetInputCommand(ContentKeyFunctions.OpenCharacterMenu, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void _setSlot(Slots slot, IEntity entity)
|
||||
{
|
||||
if (_sprite != null && entity.TryGetComponent(out ClothingComponent clothing))
|
||||
@@ -178,7 +167,7 @@ namespace Content.Client.GameObjects
|
||||
/// <summary>
|
||||
/// Temporary window to hold the basis for inventory hud
|
||||
/// </summary>
|
||||
private class InventoryWindow : SS14Window
|
||||
private class InventoryWindow : Control
|
||||
{
|
||||
private int elements_x;
|
||||
|
||||
@@ -187,13 +176,11 @@ namespace Content.Client.GameObjects
|
||||
private Dictionary<Slots, InventoryButton> InventorySlots = new Dictionary<Slots, InventoryButton>(); //ordered dictionary?
|
||||
private ClientInventoryComponent InventoryComponent;
|
||||
|
||||
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Inventory/HumanInventory.tscn");
|
||||
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Mobs/HumanInventory.tscn");
|
||||
|
||||
public InventoryWindow(ClientInventoryComponent inventory)
|
||||
{
|
||||
InventoryComponent = inventory;
|
||||
|
||||
HideOnClose = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -203,7 +190,7 @@ namespace Content.Client.GameObjects
|
||||
{
|
||||
elements_x = inventory.Columns;
|
||||
|
||||
GridContainer = (GridContainer)Contents.GetChild("PanelContainer").GetChild("CenterContainer").GetChild("GridContainer");
|
||||
GridContainer = (GridContainer)GetChild("CenterContainer").GetChild("GridContainer");
|
||||
GridContainer.Columns = elements_x;
|
||||
IndexedSlots = new List<Slots>(inventory.SlotMasks);
|
||||
|
||||
@@ -304,7 +291,7 @@ namespace Content.Client.GameObjects
|
||||
public Slots Slot;
|
||||
public EntityUid EntityUid;
|
||||
|
||||
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Inventory/StorageSlot.tscn");
|
||||
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Mobs/StorageSlot.tscn");
|
||||
|
||||
public InventoryButton(Slots slot)
|
||||
{
|
||||
21
Content.Client/GameObjects/Components/Mobs/ICharacterUI.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Content.Client.GameObjects.Components.Actor;
|
||||
using SS14.Client.UserInterface;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Mobs
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface which is gathered to assemble the character window from multiple components
|
||||
/// </summary>
|
||||
public interface ICharacterUI
|
||||
{
|
||||
/// <summary>
|
||||
/// The godot control which holds the character user interface to be included in the window
|
||||
/// </summary>
|
||||
Control Scene { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The order it will appear in the character UI, higher is lower
|
||||
/// </summary>
|
||||
UIPriority Priority { get; }
|
||||
}
|
||||
}
|
||||
160
Content.Client/GameObjects/Components/Mobs/SpeciesUI.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
using Content.Client.GameObjects.Components.Actor;
|
||||
using Content.Client.GameObjects.Components.Mobs;
|
||||
using Content.Client.Graphics.Overlays;
|
||||
using Content.Shared.GameObjects;
|
||||
using SS14.Client.GameObjects;
|
||||
using SS14.Client.Interfaces.Graphics.Overlays;
|
||||
using SS14.Client.Interfaces.ResourceManagement;
|
||||
using SS14.Client.Player;
|
||||
using SS14.Client.ResourceManagement;
|
||||
using SS14.Client.UserInterface;
|
||||
using SS14.Client.UserInterface.Controls;
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.Network;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Log;
|
||||
using SS14.Shared.Utility;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Content.Client.GameObjects
|
||||
{
|
||||
/// <summary>
|
||||
/// A character UI component which shows the current damage state of the mob (living/dead)
|
||||
/// </summary>
|
||||
public class SpeciesUI : Component, ICharacterUI
|
||||
{
|
||||
public override string Name => "Species";
|
||||
|
||||
public override uint? NetID => ContentNetIDs.SPECIES;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the godot control for the species window
|
||||
/// </summary>
|
||||
private SpeciesWindow _window;
|
||||
|
||||
/// <summary>
|
||||
/// An enum representing the current state being applied to the user
|
||||
/// </summary>
|
||||
private ScreenEffects _currentEffect = ScreenEffects.None;
|
||||
|
||||
// Required dependencies
|
||||
[Dependency] private readonly IOverlayManager _overlayManager;
|
||||
[Dependency] private readonly IPlayerManager _playerManager;
|
||||
|
||||
//Relevant interface implementation for the character UI controller
|
||||
public Control Scene => _window;
|
||||
public UIPriority Priority => UIPriority.Species;
|
||||
|
||||
/// <summary>
|
||||
/// Allows calculating if we need to act due to this component being controlled by the current mob
|
||||
/// </summary>
|
||||
private bool CurrentlyControlled => _playerManager.LocalPlayer.ControlledEntity == Owner;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the screen effects that can be applied mapped ot their relevant overlay
|
||||
/// </summary>
|
||||
private Dictionary<ScreenEffects, IOverlay> EffectsDictionary;
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
|
||||
_window.Dispose();
|
||||
}
|
||||
|
||||
public override void OnAdd()
|
||||
{
|
||||
base.OnAdd();
|
||||
|
||||
IoCManager.InjectDependencies(this);
|
||||
_window = new SpeciesWindow();
|
||||
|
||||
EffectsDictionary = new Dictionary<ScreenEffects, IOverlay>()
|
||||
{
|
||||
{ ScreenEffects.CircleMask, new CircleMaskOverlay() },
|
||||
{ ScreenEffects.GradientCircleMask, new GradientCircleMask() }
|
||||
};
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case HudStateChange msg:
|
||||
if(CurrentlyControlled)
|
||||
{
|
||||
ChangeHudIcon(msg);
|
||||
}
|
||||
break;
|
||||
|
||||
case PlayerAttachedMsg _:
|
||||
ApplyOverlay();
|
||||
break;
|
||||
|
||||
case PlayerDetachedMsg _:
|
||||
RemoveOverlay();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeHudIcon(HudStateChange changemessage)
|
||||
{
|
||||
_window.SetIcon(changemessage);
|
||||
SetOverlay(changemessage);
|
||||
}
|
||||
|
||||
private void SetOverlay(HudStateChange message)
|
||||
{
|
||||
RemoveOverlay();
|
||||
|
||||
_currentEffect = message.effect;
|
||||
|
||||
ApplyOverlay();
|
||||
}
|
||||
|
||||
private void RemoveOverlay()
|
||||
{
|
||||
if (_currentEffect != ScreenEffects.None)
|
||||
{
|
||||
var appliedeffect = EffectsDictionary[_currentEffect];
|
||||
_overlayManager.RemoveOverlay(nameof(appliedeffect));
|
||||
}
|
||||
|
||||
_currentEffect = ScreenEffects.None;
|
||||
}
|
||||
|
||||
private void ApplyOverlay()
|
||||
{
|
||||
if (_currentEffect != ScreenEffects.None)
|
||||
{
|
||||
_overlayManager.AddOverlay(EffectsDictionary[_currentEffect]);
|
||||
}
|
||||
}
|
||||
|
||||
private class SpeciesWindow : Control
|
||||
{
|
||||
private TextureRect _textureRect;
|
||||
|
||||
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Mobs/Species.tscn");
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_textureRect = (TextureRect)GetChild("TextureRect");
|
||||
}
|
||||
|
||||
public void SetIcon(HudStateChange changemessage)
|
||||
{
|
||||
if (!IoCManager.Resolve<IResourceCache>().TryGetResource<TextureResource>(new ResourcePath("/Textures") / changemessage.StateSprite, out var newtexture))
|
||||
{
|
||||
Logger.Info("The Species Health Sprite {0} Does Not Exist", new ResourcePath("/Textures") / changemessage.StateSprite);
|
||||
return;
|
||||
}
|
||||
|
||||
_textureRect.Texture = newtexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Content.Client/Graphics/Overlays/CircleMaskOverlay.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using SS14.Client.Graphics.Drawing;
|
||||
using SS14.Client.Graphics.Overlays;
|
||||
using SS14.Client.Graphics.Shaders;
|
||||
using SS14.Client.Interfaces.Graphics.ClientEye;
|
||||
using SS14.Client.Interfaces.Graphics.Overlays;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Maths;
|
||||
using SS14.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Graphics.Overlays
|
||||
{
|
||||
public class CircleMaskOverlay : Overlay
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
||||
[Dependency] private readonly IEyeManager _eyeManager;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
|
||||
public CircleMaskOverlay() : base(nameof(CircleMaskOverlay))
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
Shader = _prototypeManager.Index<ShaderPrototype>("circlemask").Instance();
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandle handle)
|
||||
{
|
||||
var worldHandle = (DrawingHandleWorld)handle;
|
||||
var viewport = _eyeManager.GetWorldViewport();
|
||||
worldHandle.DrawRect(viewport, Color.White);
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Content.Client/Graphics/Overlays/GradientCircleMask.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using SS14.Client.Graphics.Drawing;
|
||||
using SS14.Client.Graphics.Overlays;
|
||||
using SS14.Client.Graphics.Shaders;
|
||||
using SS14.Client.Interfaces.Graphics.ClientEye;
|
||||
using SS14.Client.Interfaces.Graphics.Overlays;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Maths;
|
||||
using SS14.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Graphics.Overlays
|
||||
{
|
||||
public class GradientCircleMask : Overlay
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
||||
[Dependency] private readonly IEyeManager _eyeManager;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
|
||||
public GradientCircleMask() : base(nameof(GradientCircleMask))
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
Shader = _prototypeManager.Index<ShaderPrototype>("gradientcirclemask").Instance();
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandle handle)
|
||||
{
|
||||
var worldHandle = (DrawingHandleWorld)handle;
|
||||
var viewport = _eyeManager.GetWorldViewport();
|
||||
worldHandle.DrawRect(viewport, Color.White);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@
|
||||
<Compile Include="Administration\AGhost.cs" />
|
||||
<Compile Include="AI\AimShootLifeProcessor.cs" />
|
||||
<Compile Include="EntryPoint.cs" />
|
||||
<Compile Include="GameObjects\Components\Damage\DamageThreshold.cs" />
|
||||
<Compile Include="GameObjects\Components\Doors\ServerDoorComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Interactable\HandheldLightComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Interactable\Tools\BaseTool.cs" />
|
||||
@@ -79,7 +80,11 @@
|
||||
<Compile Include="GameObjects\Components\Items\Storage\StoreableComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Items\Storage\ServerStorageComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Items\Storage\ItemComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Mobs\DamageStates.cs" />
|
||||
<Compile Include="GameObjects\Components\Mobs\DamageThresholdTemplates\DamageThresholdTemplates.cs" />
|
||||
<Compile Include="GameObjects\Components\Mobs\DamageThresholdTemplates\HumanTemplate.cs" />
|
||||
<Compile Include="GameObjects\Components\Mobs\MindComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Mobs\SpeciesComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Power\PowerCellComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Power\PowerStorageComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Power\PowerGeneratorComponent.cs" />
|
||||
@@ -96,6 +101,7 @@
|
||||
<Compile Include="GameObjects\Components\Weapon\Ranged\Projectile\ProjectileWeapon.cs" />
|
||||
<Compile Include="GameObjects\Components\Weapon\Ranged\RangedWeapon.cs" />
|
||||
<Compile Include="GameObjects\ContainerSlot.cs" />
|
||||
<Compile Include="GameObjects\EntitySystems\ActionBlockerSystem.cs" />
|
||||
<Compile Include="GameObjects\EntitySystems\Click\ExamineSystem.cs" />
|
||||
<Compile Include="GameObjects\EntitySystems\Click\InteractionSystem.cs" />
|
||||
<Compile Include="GameObjects\EntitySystems\DoorSystem.cs" />
|
||||
|
||||
@@ -115,6 +115,7 @@ namespace Content.Server
|
||||
factory.RegisterIgnore("ConstructionGhost");
|
||||
|
||||
factory.Register<MindComponent>();
|
||||
factory.Register<SpeciesComponent>();
|
||||
|
||||
IoCManager.Register<ISharedNotifyManager, ServerNotifyManager>();
|
||||
IoCManager.Register<IServerNotifyManager, ServerNotifyManager>();
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
using Content.Shared.GameObjects;
|
||||
using System;
|
||||
|
||||
namespace Content.Server.GameObjects
|
||||
{
|
||||
/// <summary>
|
||||
/// Triggers an event when values rise above or drop below this threshold
|
||||
/// </summary>
|
||||
public struct DamageThreshold
|
||||
{
|
||||
public DamageType DamageType { get; }
|
||||
public int Value { get; }
|
||||
public ThresholdType ThresholdType { get; }
|
||||
|
||||
public DamageThreshold(DamageType damageType, int value, ThresholdType thresholdType)
|
||||
{
|
||||
DamageType = damageType;
|
||||
Value = value;
|
||||
ThresholdType = thresholdType;
|
||||
}
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
return obj is DamageThreshold && this == (DamageThreshold)obj;
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return DamageType.GetHashCode() ^ Value.GetHashCode();
|
||||
}
|
||||
public static bool operator ==(DamageThreshold x, DamageThreshold y)
|
||||
{
|
||||
return x.DamageType == y.DamageType && x.Value == y.Value;
|
||||
}
|
||||
public static bool operator !=(DamageThreshold x, DamageThreshold y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ThresholdType
|
||||
{
|
||||
None,
|
||||
Destruction,
|
||||
Death,
|
||||
Critical,
|
||||
HUDUpdate
|
||||
}
|
||||
|
||||
public class DamageThresholdPassedEventArgs : EventArgs
|
||||
{
|
||||
public DamageThreshold DamageThreshold { get; }
|
||||
public bool Passed { get; }
|
||||
|
||||
public DamageThresholdPassedEventArgs(DamageThreshold threshold, bool passed)
|
||||
{
|
||||
DamageThreshold = threshold;
|
||||
Passed = passed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,11 @@ namespace Content.Server.GameObjects
|
||||
/// A component that handles receiving damage and healing,
|
||||
/// as well as informing other components of it.
|
||||
/// </summary>
|
||||
public class DamageableComponent : Component, IDamageableComponent
|
||||
public class DamageableComponent : SharedDamageableComponent, IDamageableComponent
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Damageable";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override uint? NetID => ContentNetIDs.DAMAGEABLE;
|
||||
|
||||
/// <summary>
|
||||
/// The resistance set of this object.
|
||||
/// Affects receiving damage of various types.
|
||||
@@ -33,11 +30,17 @@ namespace Content.Server.GameObjects
|
||||
[ViewVariables]
|
||||
public ResistanceSet Resistances { get; private set; }
|
||||
|
||||
Dictionary<DamageType, int> CurrentDamage = new Dictionary<DamageType, int>();
|
||||
Dictionary<DamageType, List<int>> Thresholds = new Dictionary<DamageType, List<int>>();
|
||||
public IReadOnlyDictionary<DamageType, int> CurrentDamage => _currentDamage;
|
||||
private Dictionary<DamageType, int> _currentDamage = new Dictionary<DamageType, int>();
|
||||
|
||||
Dictionary<DamageType, List<DamageThreshold>> Thresholds = new Dictionary<DamageType, List<DamageThreshold>>();
|
||||
|
||||
public event EventHandler<DamageThresholdPassedEventArgs> DamageThresholdPassed;
|
||||
|
||||
public override ComponentState GetComponentState()
|
||||
{
|
||||
return new DamageComponentState(_currentDamage);
|
||||
}
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
@@ -55,9 +58,10 @@ namespace Content.Server.GameObjects
|
||||
{
|
||||
base.Initialize();
|
||||
InitializeDamageType(DamageType.Total);
|
||||
if (Owner is IOnDamageBehavior damageBehavior)
|
||||
|
||||
foreach (var damagebehavior in Owner.GetAllComponents<IOnDamageBehavior>())
|
||||
{
|
||||
AddThresholdsFrom(damageBehavior);
|
||||
AddThresholdsFrom(damagebehavior);
|
||||
}
|
||||
|
||||
RecalculateComponentThresholds();
|
||||
@@ -72,7 +76,7 @@ namespace Content.Server.GameObjects
|
||||
}
|
||||
InitializeDamageType(damageType);
|
||||
|
||||
int oldValue = CurrentDamage[damageType];
|
||||
int oldValue = _currentDamage[damageType];
|
||||
int oldTotalValue = -1;
|
||||
|
||||
if (amount == 0)
|
||||
@@ -81,13 +85,13 @@ namespace Content.Server.GameObjects
|
||||
}
|
||||
|
||||
amount = Resistances.CalculateDamage(damageType, amount);
|
||||
CurrentDamage[damageType] = Math.Max(0, CurrentDamage[damageType] + amount);
|
||||
_currentDamage[damageType] = Math.Max(0, _currentDamage[damageType] + amount);
|
||||
UpdateForDamageType(damageType, oldValue);
|
||||
|
||||
if (Resistances.AppliesToTotal(damageType))
|
||||
{
|
||||
oldTotalValue = CurrentDamage[DamageType.Total];
|
||||
CurrentDamage[DamageType.Total] = Math.Max(0, CurrentDamage[DamageType.Total] + amount);
|
||||
oldTotalValue = _currentDamage[DamageType.Total];
|
||||
_currentDamage[DamageType.Total] = Math.Max(0, _currentDamage[DamageType.Total] + amount);
|
||||
UpdateForDamageType(DamageType.Total, oldTotalValue);
|
||||
}
|
||||
}
|
||||
@@ -104,7 +108,7 @@ namespace Content.Server.GameObjects
|
||||
|
||||
void UpdateForDamageType(DamageType damageType, int oldValue)
|
||||
{
|
||||
int change = CurrentDamage[damageType] - oldValue;
|
||||
int change = _currentDamage[damageType] - oldValue;
|
||||
|
||||
if (change == 0)
|
||||
{
|
||||
@@ -113,11 +117,12 @@ namespace Content.Server.GameObjects
|
||||
|
||||
int changeSign = Math.Sign(change);
|
||||
|
||||
foreach (int value in Thresholds[damageType])
|
||||
foreach (var threshold in Thresholds[damageType])
|
||||
{
|
||||
if (((value * changeSign) > (oldValue * changeSign)) && ((value * changeSign) <= (CurrentDamage[damageType] * changeSign)))
|
||||
var value = threshold.Value;
|
||||
if (((value * changeSign) > (oldValue * changeSign)) && ((value * changeSign) <= (_currentDamage[damageType] * changeSign)))
|
||||
{
|
||||
var args = new DamageThresholdPassedEventArgs(new DamageThreshold(damageType, value), (changeSign > 0));
|
||||
var args = new DamageThresholdPassedEventArgs(threshold, (changeSign > 0));
|
||||
DamageThresholdPassed?.Invoke(this, args);
|
||||
}
|
||||
}
|
||||
@@ -142,62 +147,23 @@ namespace Content.Server.GameObjects
|
||||
|
||||
foreach (DamageThreshold threshold in thresholds)
|
||||
{
|
||||
if (!Thresholds[threshold.DamageType].Contains(threshold.Value))
|
||||
if (!Thresholds[threshold.DamageType].Contains(threshold))
|
||||
{
|
||||
Thresholds[threshold.DamageType].Add(threshold.Value);
|
||||
Thresholds[threshold.DamageType].Add(threshold);
|
||||
}
|
||||
}
|
||||
|
||||
DamageThresholdPassed += onDamageBehavior.OnDamageThresholdPassed;
|
||||
}
|
||||
|
||||
void InitializeDamageType(DamageType damageType)
|
||||
{
|
||||
if (!CurrentDamage.ContainsKey(damageType))
|
||||
if (!_currentDamage.ContainsKey(damageType))
|
||||
{
|
||||
CurrentDamage.Add(damageType, 0);
|
||||
Thresholds.Add(damageType, new List<int>());
|
||||
_currentDamage.Add(damageType, 0);
|
||||
Thresholds.Add(damageType, new List<DamageThreshold>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct DamageThreshold
|
||||
{
|
||||
public DamageType DamageType { get; }
|
||||
public int Value { get; }
|
||||
|
||||
public DamageThreshold(DamageType damageType, int value)
|
||||
{
|
||||
DamageType = damageType;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
return obj is DamageThreshold && this == (DamageThreshold)obj;
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return DamageType.GetHashCode() ^ Value.GetHashCode();
|
||||
}
|
||||
public static bool operator ==(DamageThreshold x, DamageThreshold y)
|
||||
{
|
||||
return x.DamageType == y.DamageType && x.Value == y.Value;
|
||||
}
|
||||
public static bool operator !=(DamageThreshold x, DamageThreshold y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
}
|
||||
|
||||
public class DamageThresholdPassedEventArgs : EventArgs
|
||||
{
|
||||
public DamageThreshold DamageThreshold { get; }
|
||||
public bool Passed { get; }
|
||||
|
||||
public DamageThresholdPassedEventArgs(DamageThreshold threshold, bool passed)
|
||||
{
|
||||
DamageThreshold = threshold;
|
||||
Passed = passed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,18 +43,7 @@ namespace Content.Server.GameObjects
|
||||
serializer.DataReadFunction("thresholdtype", DamageType.Total, type => damageType = type);
|
||||
serializer.DataReadFunction("thresholdvalue", 0, val => damageValue = val);
|
||||
|
||||
Threshold = new DamageThreshold(damageType, damageValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
if (Owner.TryGetComponent<DamageableComponent>(out DamageableComponent damageable))
|
||||
{
|
||||
damageable.DamageThresholdPassed += OnDamageThresholdPassed;
|
||||
Threshold = new DamageThreshold(damageType, damageValue, ThresholdType.Destruction);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,9 @@
|
||||
using System;
|
||||
using Content.Shared.GameObjects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Content.Server.GameObjects
|
||||
{
|
||||
/// <summary>
|
||||
/// Damage types used in-game.
|
||||
/// Total should never be used directly - it's a derived value.
|
||||
/// </summary>
|
||||
public enum DamageType
|
||||
{
|
||||
Total,
|
||||
Brute,
|
||||
Heat,
|
||||
Cold,
|
||||
Acid,
|
||||
Toxic,
|
||||
Electric
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resistance set used by damageable objects.
|
||||
/// For each damage type, has a coefficient, damage reduction and "included in total" value.
|
||||
|
||||
104
Content.Server/GameObjects/Components/Mobs/DamageStates.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using SS14.Server.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Maths;
|
||||
|
||||
namespace Content.Server.GameObjects
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the blocking effect of each damage state, and what effects to apply upon entering or exiting the state
|
||||
/// </summary>
|
||||
public interface DamageState : IActionBlocker
|
||||
{
|
||||
void EnterState(IEntity entity);
|
||||
|
||||
void ExitState(IEntity entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Standard state that a species is at with no damage or negative effect
|
||||
/// </summary>
|
||||
public struct NormalState : DamageState
|
||||
{
|
||||
public void EnterState(IEntity entity){}
|
||||
|
||||
public void ExitState(IEntity entity){}
|
||||
|
||||
bool IActionBlocker.CanInteract()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanMove()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanUse()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A state in which you are disabled from acting due to damage
|
||||
/// </summary>
|
||||
public struct CriticalState : DamageState
|
||||
{
|
||||
public void EnterState(IEntity entity) { }
|
||||
|
||||
public void ExitState(IEntity entity) { }
|
||||
|
||||
bool IActionBlocker.CanInteract()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanMove()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanUse()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A damage state which will allow ghosting out of mobs
|
||||
/// </summary>
|
||||
public struct DeadState : DamageState
|
||||
{
|
||||
public void EnterState(IEntity entity)
|
||||
{
|
||||
if(entity.TryGetComponent(out SpriteComponent sprite))
|
||||
{
|
||||
sprite.Rotation = sprite.Rotation + Angle.FromDegrees(90);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExitState(IEntity entity)
|
||||
{
|
||||
if (entity.TryGetComponent(out SpriteComponent sprite))
|
||||
{
|
||||
sprite.Rotation = sprite.Rotation - Angle.FromDegrees(90);
|
||||
}
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanInteract()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanMove()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanUse()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.GameObjects;
|
||||
|
||||
namespace Content.Server.GameObjects
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the threshold values for each damage state for any kind of species
|
||||
/// </summary>
|
||||
public abstract class DamageTemplates
|
||||
{
|
||||
public abstract List<DamageThreshold> HealthHudThresholds { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Changes the hud state when a threshold is reached
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
/// <param name="damage"></param>
|
||||
/// <returns></returns>
|
||||
public abstract HudStateChange ChangeHudState(DamageableComponent damage);
|
||||
|
||||
//public abstract ResistanceSet resistanceset { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Shows allowed states, ordered by priority, closest to last value to have threshold reached is preferred
|
||||
/// </summary>
|
||||
public abstract List<(DamageType, int, ThresholdType)> AllowedStates { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Map of ALL POSSIBLE damage states to the threshold enum value that will trigger them, normal state wont be triggered by this value but is a default that is fell back onto
|
||||
/// </summary>
|
||||
public static Dictionary<ThresholdType, DamageState> StateThresholdMap = new Dictionary<ThresholdType, DamageState>()
|
||||
{
|
||||
{ ThresholdType.None, new NormalState() },
|
||||
{ ThresholdType.Critical, new CriticalState() },
|
||||
{ ThresholdType.Death, new DeadState() }
|
||||
};
|
||||
|
||||
public List<DamageThreshold> DamageThresholds
|
||||
{
|
||||
get
|
||||
{
|
||||
List<DamageThreshold> thresholds = new List<DamageThreshold>();
|
||||
foreach (var element in AllowedStates)
|
||||
{
|
||||
thresholds.Add(new DamageThreshold(element.Item1, element.Item2, element.Item3));
|
||||
}
|
||||
return thresholds;
|
||||
}
|
||||
}
|
||||
|
||||
public ThresholdType CalculateDamageState(DamageableComponent damage)
|
||||
{
|
||||
ThresholdType healthstate = ThresholdType.None;
|
||||
foreach(var element in AllowedStates)
|
||||
{
|
||||
if(damage.CurrentDamage[element.Item1] >= element.Item2)
|
||||
{
|
||||
healthstate = element.Item3;
|
||||
}
|
||||
}
|
||||
|
||||
return healthstate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using Content.Shared.GameObjects;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Content.Server.GameObjects
|
||||
{
|
||||
public class Human : DamageTemplates
|
||||
{
|
||||
int critvalue = 200;
|
||||
int normalstates = 6;
|
||||
//string startsprite = "human0";
|
||||
|
||||
public override List<(DamageType, int, ThresholdType)> AllowedStates => new List<(DamageType, int, ThresholdType)>()
|
||||
{
|
||||
(DamageType.Total, critvalue, ThresholdType.Critical),
|
||||
(DamageType.Total, 300, ThresholdType.Death),
|
||||
};
|
||||
|
||||
public override List<DamageThreshold> HealthHudThresholds
|
||||
{
|
||||
get
|
||||
{
|
||||
List<DamageThreshold> thresholds = new List<DamageThreshold>();
|
||||
thresholds.Add(new DamageThreshold(DamageType.Total, 1, ThresholdType.HUDUpdate));
|
||||
for (var i = 1; i <= normalstates; i++)
|
||||
{
|
||||
thresholds.Add(new DamageThreshold(DamageType.Total, i * critvalue / normalstates, ThresholdType.HUDUpdate));
|
||||
}
|
||||
return thresholds; //we don't need to respecify the state damage thresholds since we'll update hud on damage state changes as well
|
||||
}
|
||||
}
|
||||
|
||||
public override HudStateChange ChangeHudState(DamageableComponent damage)
|
||||
{
|
||||
ThresholdType healthstate = CalculateDamageState(damage);
|
||||
switch (healthstate)
|
||||
{
|
||||
case ThresholdType.None:
|
||||
var totaldamage = damage.CurrentDamage[DamageType.Total];
|
||||
if (totaldamage > critvalue)
|
||||
{
|
||||
throw new System.InvalidOperationException(); //these should all be below the crit value, possibly going over multiple thresholds at once?
|
||||
}
|
||||
var modifier = totaldamage / (critvalue / normalstates); //integer division floors towards zero
|
||||
return new HudStateChange()
|
||||
{
|
||||
StateSprite = "Mob/UI/Human/human" + modifier.ToString() + ".png",
|
||||
effect = ScreenEffects.None
|
||||
};
|
||||
case ThresholdType.Critical:
|
||||
return new HudStateChange()
|
||||
{
|
||||
StateSprite = "Mob/UI/Human/humancrit-0.png", //TODO: display as gif or alternate with -0 and -1 as frames
|
||||
effect = ScreenEffects.GradientCircleMask
|
||||
};
|
||||
case ThresholdType.Death:
|
||||
return new HudStateChange()
|
||||
{
|
||||
StateSprite = "Mob/UI/Human/humandead.png",
|
||||
effect = ScreenEffects.CircleMask
|
||||
};
|
||||
default:
|
||||
throw new System.InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.GameObjects;
|
||||
using SS14.Server.GameObjects;
|
||||
using SS14.Shared.ContentPack;
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.Network;
|
||||
using SS14.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.GameObjects
|
||||
{
|
||||
public class SpeciesComponent : Component, IActionBlocker, IOnDamageBehavior
|
||||
{
|
||||
public override string Name => "Species";
|
||||
|
||||
public override uint? NetID => ContentNetIDs.SPECIES;
|
||||
|
||||
/// <summary>
|
||||
/// Damagestates are reached by reaching a certain damage threshold, they will block actions after being reached
|
||||
/// </summary>
|
||||
public DamageState CurrentDamageState { get; private set; } = new NormalState();
|
||||
|
||||
/// <summary>
|
||||
/// Damage state enum for current health, set only via change damage state //TODO: SETTER
|
||||
/// </summary>
|
||||
private ThresholdType currentstate = ThresholdType.None;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the damage template which controls the threshold and resistance settings for this species type
|
||||
/// </summary>
|
||||
private DamageTemplates DamageTemplate;
|
||||
|
||||
/// <summary>
|
||||
/// Variable for serialization
|
||||
/// </summary>
|
||||
private string templatename;
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataField(ref templatename, "Template", "Human");
|
||||
|
||||
Type type = AppDomain.CurrentDomain.GetAssemblyByName("Content.Server").GetType("Content.Server.GameObjects." + templatename);
|
||||
DamageTemplate = (DamageTemplates)Activator.CreateInstance(type);
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case PlayerAttachedMsg _:
|
||||
var hudstatechange = DamageTemplate.ChangeHudState(Owner.GetComponent<DamageableComponent>());
|
||||
SendNetworkMessage(hudstatechange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanMove()
|
||||
{
|
||||
return CurrentDamageState.CanMove();
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanInteract()
|
||||
{
|
||||
return CurrentDamageState.CanInteract();
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanUse()
|
||||
{
|
||||
return CurrentDamageState.CanUse();
|
||||
}
|
||||
|
||||
List<DamageThreshold> IOnDamageBehavior.GetAllDamageThresholds()
|
||||
{
|
||||
var thresholdlist = DamageTemplate.DamageThresholds;
|
||||
thresholdlist.AddRange(DamageTemplate.HealthHudThresholds);
|
||||
return thresholdlist;
|
||||
}
|
||||
|
||||
void IOnDamageBehavior.OnDamageThresholdPassed(object damageable, DamageThresholdPassedEventArgs e)
|
||||
{
|
||||
DamageableComponent damage = (DamageableComponent)damageable;
|
||||
|
||||
if(e.DamageThreshold.ThresholdType != ThresholdType.HUDUpdate)
|
||||
{
|
||||
ChangeDamageState(DamageTemplate.CalculateDamageState(damage));
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent(out BasicActorComponent actor)) //specifies if we have a client to update the hud for
|
||||
{
|
||||
var hudstatechange = DamageTemplate.ChangeHudState(damage);
|
||||
SendNetworkMessage(hudstatechange);
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeDamageState(ThresholdType threshold)
|
||||
{
|
||||
if(threshold == currentstate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentDamageState.ExitState(Owner);
|
||||
CurrentDamageState = DamageTemplates.StateThresholdMap[threshold];
|
||||
CurrentDamageState.EnterState(Owner);
|
||||
|
||||
currentstate = threshold;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
using SS14.Shared.Utility;
|
||||
using Content.Shared.GameObjects;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Projectiles
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Projectiles;
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.Physics;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
|
||||
@@ -11,6 +11,7 @@ using SS14.Shared.Interfaces.Timing;
|
||||
using SS14.Shared.GameObjects.EntitySystemMessages;
|
||||
using SS14.Shared.Serialization;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.GameObjects;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Weapon.Melee
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SS14.Server.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects;
|
||||
using SS14.Server.GameObjects.EntitySystems;
|
||||
using SS14.Shared.Audio;
|
||||
using SS14.Shared.GameObjects.EntitySystemMessages;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
@@ -9,6 +10,7 @@ using SS14.Shared.IoC;
|
||||
using SS14.Shared.Map;
|
||||
using SS14.Shared.Maths;
|
||||
using SS14.Shared.Physics;
|
||||
using SS14.Shared.Serialization;
|
||||
using System;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
||||
@@ -18,7 +20,16 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
||||
private const float MaxLength = 20;
|
||||
public override string Name => "HitscanWeapon";
|
||||
|
||||
private const string SpriteName = "Objects/laser.png";
|
||||
string Spritename = "Objects/laser.png";
|
||||
int Damage = 10;
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataField(ref Spritename, "sprite", "Objects/laser.png");
|
||||
serializer.DataField(ref Damage, "damage", 10);
|
||||
}
|
||||
|
||||
protected override void Fire(IEntity user, GridLocalCoordinates clicklocation)
|
||||
{
|
||||
@@ -37,7 +48,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
||||
{
|
||||
if (ray.HitEntity != null && ray.HitEntity.TryGetComponent(out DamageableComponent damage))
|
||||
{
|
||||
damage.TakeDamage(DamageType.Heat, 10);
|
||||
damage.TakeDamage(DamageType.Heat, Damage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +59,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
||||
var offset = angle.ToVec() * dist / 2;
|
||||
var message = new EffectSystemMessage
|
||||
{
|
||||
EffectSprite = SpriteName,
|
||||
EffectSprite = Spritename,
|
||||
Born = time,
|
||||
DeathTime = time + TimeSpan.FromSeconds(1),
|
||||
Size = new Vector2(dist, 1f),
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
using SS14.Shared.GameObjects.Systems;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
|
||||
namespace Content.Server.GameObjects.EntitySystems
|
||||
{
|
||||
public interface IActionBlocker
|
||||
{
|
||||
bool CanMove();
|
||||
|
||||
bool CanInteract();
|
||||
|
||||
bool CanUse();
|
||||
}
|
||||
|
||||
public class ActionBlockerSystem : EntitySystem
|
||||
{
|
||||
public static bool CanMove(IEntity entity)
|
||||
{
|
||||
bool canmove = true;
|
||||
foreach(var actionblockercomponents in entity.GetAllComponents<IActionBlocker>())
|
||||
{
|
||||
canmove &= actionblockercomponents.CanMove(); //sets var to false if false
|
||||
}
|
||||
return canmove;
|
||||
}
|
||||
|
||||
public static bool CanInteract(IEntity entity)
|
||||
{
|
||||
bool caninteract = true;
|
||||
foreach (var actionblockercomponents in entity.GetAllComponents<IActionBlocker>())
|
||||
{
|
||||
caninteract &= actionblockercomponents.CanInteract();
|
||||
}
|
||||
return caninteract;
|
||||
}
|
||||
|
||||
public static bool CanUse(IEntity entity)
|
||||
{
|
||||
bool canuse = true;
|
||||
foreach (var actionblockercomponents in entity.GetAllComponents<IActionBlocker>())
|
||||
{
|
||||
canuse &= actionblockercomponents.CanUse();
|
||||
}
|
||||
return canuse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,10 +178,9 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
|
||||
var item = hands.GetActiveHand?.Owner;
|
||||
|
||||
if (!MobCanInteract(player))
|
||||
if (!ActionBlockerSystem.CanInteract(player))
|
||||
return;
|
||||
//TODO: Mob status code that allows or rejects interactions based on current mob status
|
||||
//Check if client should be able to see that object to click on it in the first place, prevent using locaters by firing a laser or something
|
||||
//TODO: Check if client should be able to see that object to click on it in the first place, prevent using locaters by firing a laser or something
|
||||
|
||||
|
||||
//Clicked on empty space behavior, try using ranged attack
|
||||
@@ -239,15 +238,6 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TODO function for blocking activity based on mob status
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static bool MobCanInteract(IEntity user)
|
||||
{
|
||||
return true; //Hook into future planned mob status system
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We didn't click on any entity, try doing an afterattack on the click location
|
||||
/// </summary>
|
||||
@@ -324,7 +314,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
/// <param name="used"></param>
|
||||
public static void TryUseInteraction(IEntity user, IEntity used)
|
||||
{
|
||||
if (user != null && used != null && MobCanInteract(user))
|
||||
if (user != null && used != null && ActionBlockerSystem.CanUse(user))
|
||||
{
|
||||
UseInteraction(user, used);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Server.GameObjects;
|
||||
using Content.Shared.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using System;
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="EntryPoint.cs" />
|
||||
<Compile Include="GameObjects\Components\Damage\DamageableComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Inventory\EquipmentSlotDefinitions.cs" />
|
||||
<Compile Include="GameObjects\Components\Inventory\InventoryTemplates.cs" />
|
||||
<Compile Include="GameObjects\Components\Inventory\SharedInventoryComponent.cs" />
|
||||
@@ -71,6 +72,7 @@
|
||||
<Compile Include="GameObjects\Components\Storage\SharedStorageComponent.cs" />
|
||||
<Compile Include="GameObjects\ContentNetIDs.cs" />
|
||||
<Compile Include="GameObjects\EntitySystemMessages\VerbSystemMessages.cs" />
|
||||
<Compile Include="GameObjects\Messages\Mob\HealthHud.cs" />
|
||||
<Compile Include="GameObjects\PhysicalConstants.cs" />
|
||||
<Compile Include="Interfaces\ISharedNotifyManager.cs" />
|
||||
<Compile Include="GameObjects\Verb.cs" />
|
||||
@@ -117,4 +119,4 @@
|
||||
<Compile Include="Construction\ConstructionPrototype.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Content.Shared.GameObjects
|
||||
{
|
||||
public abstract class SharedDamageableComponent : Component
|
||||
{
|
||||
public override string Name => "Damageable";
|
||||
public sealed override uint? NetID => ContentNetIDs.DAMAGEABLE;
|
||||
public sealed override Type StateType => typeof(DamageComponentState);
|
||||
}
|
||||
|
||||
// The IDs of the items get synced over the network.
|
||||
[Serializable, NetSerializable]
|
||||
public class DamageComponentState : ComponentState
|
||||
{
|
||||
public Dictionary<DamageType, int> CurrentDamage = new Dictionary<DamageType, int>();
|
||||
|
||||
public DamageComponentState(Dictionary<DamageType, int> damage) : base(ContentNetIDs.DAMAGEABLE)
|
||||
{
|
||||
CurrentDamage = damage;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Damage types used in-game.
|
||||
/// Total should never be used directly - it's a derived value.
|
||||
/// </summary>
|
||||
public enum DamageType
|
||||
{
|
||||
Total,
|
||||
Brute,
|
||||
Heat,
|
||||
Cold,
|
||||
Acid,
|
||||
Toxic,
|
||||
Electric
|
||||
}
|
||||
}
|
||||
@@ -11,5 +11,6 @@
|
||||
public const uint INVENTORY = 1006;
|
||||
public const uint POWER_DEBUG_TOOL = 1007;
|
||||
public const uint CONSTRUCTOR = 1008;
|
||||
public const uint SPECIES = 1009;
|
||||
}
|
||||
}
|
||||
|
||||
28
Content.Shared/GameObjects/Messages/Mob/HealthHud.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Serialization;
|
||||
using System;
|
||||
|
||||
namespace Content.Shared.GameObjects
|
||||
{
|
||||
/// <summary>
|
||||
/// Sends updates to the standard species health hud with the sprite to change the hud to
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public class HudStateChange : ComponentMessage
|
||||
{
|
||||
public string StateSprite;
|
||||
public ScreenEffects effect;
|
||||
|
||||
public HudStateChange()
|
||||
{
|
||||
Directed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ScreenEffects
|
||||
{
|
||||
None,
|
||||
CircleMask,
|
||||
GradientCircleMask,
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,10 @@
|
||||
|
||||
- type: Input
|
||||
context: "human"
|
||||
|
||||
- type: Species
|
||||
Template: Human
|
||||
- type: Damageable
|
||||
|
||||
- type: Eye
|
||||
zoom: 0.5, 0.5
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
sprite: Objects/laser_retro.rsi
|
||||
state: 100
|
||||
- type: HitscanWeapon
|
||||
damage: 30
|
||||
sprite: "Objects/laser.png"
|
||||
- type: Item
|
||||
Size: 24
|
||||
sprite: Objects/laser_retro.rsi
|
||||
|
||||
9
Resources/Prototypes/Shaders/shaders.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
- type: shader
|
||||
id: circlemask
|
||||
kind: source
|
||||
path: "/Shaders/circlemask.gdsl"
|
||||
|
||||
- type: shader
|
||||
id: gradientcirclemask
|
||||
kind: source
|
||||
path: "/Shaders/gradientcirclemask.gdsl"
|
||||
32
Resources/Scenes/Mobs/CharacterWindow.tscn
Normal file
@@ -0,0 +1,32 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://Scenes/SS14Window/SS14Window.tscn" type="PackedScene" id=1]
|
||||
|
||||
[node name="SS14Window" index="0" instance=ExtResource( 1 )]
|
||||
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 0.0
|
||||
margin_top = 0.0
|
||||
margin_right = 240.0
|
||||
margin_bottom = 0.0
|
||||
rect_clip_content = false
|
||||
_sections_unfolded = [ "Anchor", "Margin" ]
|
||||
|
||||
[node name="Contents" parent="." index="0"]
|
||||
|
||||
rect_clip_content = false
|
||||
|
||||
[node name="Header" parent="." index="1"]
|
||||
|
||||
rect_clip_content = false
|
||||
|
||||
[node name="Header Text" parent="Header" index="0"]
|
||||
|
||||
rect_clip_content = false
|
||||
text = "Character Info"
|
||||
|
||||
[node name="CloseButton" parent="Header" index="1"]
|
||||
|
||||
rect_clip_content = false
|
||||
|
||||
|
||||
@@ -1,22 +1,12 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
[gd_scene format=2]
|
||||
|
||||
[ext_resource path="res://Scenes/SS14Window/SS14Window.tscn" type="PackedScene" id=1]
|
||||
|
||||
[node name="SS14Window" index="0" instance=ExtResource( 1 )]
|
||||
|
||||
margin_right = 403.0
|
||||
rect_clip_content = false
|
||||
|
||||
[node name="Contents" parent="." index="0"]
|
||||
|
||||
rect_clip_content = false
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="Contents" index="0"]
|
||||
[node name="PanelContainer" type="PanelContainer"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
anchor_bottom = 0.0
|
||||
margin_bottom = 400.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
@@ -25,7 +15,7 @@ size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
_sections_unfolded = [ "Anchor", "Grow Direction", "Margin", "Mouse", "Rect", "Size Flags", "Theme" ]
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="Contents/PanelContainer" index="0"]
|
||||
[node name="CenterContainer" type="CenterContainer" parent="." index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
@@ -33,8 +23,8 @@ anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 7.0
|
||||
margin_top = 7.0
|
||||
margin_right = 276.0
|
||||
margin_bottom = 424.0
|
||||
margin_right = 1017.0
|
||||
margin_bottom = 393.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
@@ -44,16 +34,16 @@ size_flags_vertical = 1
|
||||
use_top_left = false
|
||||
_sections_unfolded = [ "Anchor", "Focus", "Grow Direction", "Hint", "Margin", "Mouse", "Rect", "Size Flags", "Theme" ]
|
||||
|
||||
[node name="GridContainer" type="GridContainer" parent="Contents/PanelContainer/CenterContainer" index="0"]
|
||||
[node name="GridContainer" type="GridContainer" parent="CenterContainer" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 134.0
|
||||
margin_top = 208.0
|
||||
margin_right = 134.0
|
||||
margin_bottom = 208.0
|
||||
margin_left = 505.0
|
||||
margin_top = 193.0
|
||||
margin_right = 505.0
|
||||
margin_bottom = 193.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
@@ -63,17 +53,4 @@ size_flags_vertical = 1
|
||||
columns = 3
|
||||
_sections_unfolded = [ "Anchor", "Focus", "Grow Direction", "Hint", "Margin", "Material", "Mouse", "Rect", "Size Flags", "Theme", "custom_constants" ]
|
||||
|
||||
[node name="Header" parent="." index="1"]
|
||||
|
||||
rect_clip_content = false
|
||||
|
||||
[node name="Header Text" parent="Header" index="0"]
|
||||
|
||||
rect_clip_content = false
|
||||
text = "I dont how to not use a window"
|
||||
|
||||
[node name="CloseButton" parent="Header" index="1"]
|
||||
|
||||
rect_clip_content = false
|
||||
|
||||
|
||||
34
Resources/Scenes/Mobs/Species.tscn
Normal file
@@ -0,0 +1,34 @@
|
||||
[gd_scene format=2]
|
||||
|
||||
[node name="Control" type="Control" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 0.0
|
||||
margin_bottom = 64.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
_sections_unfolded = [ "Anchor", "Grow Direction", "Margin", "Rect" ]
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="." index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
expand = true
|
||||
stretch_mode = 6
|
||||
_sections_unfolded = [ "Anchor", "Grow Direction", "Margin" ]
|
||||
|
||||
|
||||
16
Resources/Shaders/circlemask.gdsl
Normal file
@@ -0,0 +1,16 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
float circle(in vec2 _st, in float _radius){
|
||||
vec2 dist = _st-vec2(0.5);
|
||||
return smoothstep(_radius-(_radius*0.01),
|
||||
_radius+(_radius*0.01),
|
||||
dot(dist,dist)*4.0);
|
||||
}
|
||||
|
||||
void fragment(){
|
||||
vec2 st = FRAGCOORD.xy*SCREEN_PIXEL_SIZE.xy;
|
||||
|
||||
COLOR = texture(TEXTURE, UV);
|
||||
COLOR.rgb = vec3(0);
|
||||
COLOR.a = circle(st,0.05);
|
||||
}
|
||||
10
Resources/Shaders/gradientcirclemask.gdsl
Normal file
@@ -0,0 +1,10 @@
|
||||
shader_type canvas_item;
|
||||
uniform float percentagedistanceshow = 0.1;
|
||||
uniform float gradientfalloffwidth = 0.2;
|
||||
|
||||
void fragment() {
|
||||
float dist = distance(UV, vec2(0.5, 0.5));
|
||||
float fromdiskdist = dist - percentagedistanceshow;
|
||||
COLOR.a = max(0, min(1.0, 2.0*dist/percentagedistanceshow - 2.0));
|
||||
COLOR.rgb = vec3(1,1,1) - vec3(fromdiskdist,fromdiskdist,fromdiskdist)/gradientfalloffwidth;
|
||||
}
|
||||
BIN
Resources/Textures/Mob/UI/Human/human0.png
Normal file
|
After Width: | Height: | Size: 233 B |
BIN
Resources/Textures/Mob/UI/Human/human1.png
Normal file
|
After Width: | Height: | Size: 214 B |
BIN
Resources/Textures/Mob/UI/Human/human2.png
Normal file
|
After Width: | Height: | Size: 214 B |
BIN
Resources/Textures/Mob/UI/Human/human3.png
Normal file
|
After Width: | Height: | Size: 214 B |
BIN
Resources/Textures/Mob/UI/Human/human4.png
Normal file
|
After Width: | Height: | Size: 214 B |
BIN
Resources/Textures/Mob/UI/Human/human5.png
Normal file
|
After Width: | Height: | Size: 214 B |
BIN
Resources/Textures/Mob/UI/Human/human6-0.png
Normal file
|
After Width: | Height: | Size: 214 B |
BIN
Resources/Textures/Mob/UI/Human/human6-1.png
Normal file
|
After Width: | Height: | Size: 240 B |
BIN
Resources/Textures/Mob/UI/Human/humancrit-0.png
Normal file
|
After Width: | Height: | Size: 252 B |
BIN
Resources/Textures/Mob/UI/Human/humancrit-1.png
Normal file
|
After Width: | Height: | Size: 252 B |
BIN
Resources/Textures/Mob/UI/Human/humandead.png
Normal file
|
After Width: | Height: | Size: 207 B |