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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="EntryPoint.cs" />
|
<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\Clothing\ClothingComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Inventory\ClientInventoryComponent.cs" />
|
|
||||||
<Compile Include="GameObjects\Components\Items\ItemComponent.cs" />
|
<Compile Include="GameObjects\Components\Items\ItemComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Power\ApcBoundUserInterface.cs" />
|
<Compile Include="GameObjects\Components\Power\ApcBoundUserInterface.cs" />
|
||||||
<Compile Include="GameObjects\Components\Power\PowerCellVisualizer2D.cs" />
|
<Compile Include="GameObjects\Components\Power\PowerCellVisualizer2D.cs" />
|
||||||
@@ -81,6 +85,8 @@
|
|||||||
<Compile Include="GameObjects\EntitySystems\ClientNotifySystem.cs" />
|
<Compile Include="GameObjects\EntitySystems\ClientNotifySystem.cs" />
|
||||||
<Compile Include="GameObjects\EntitySystems\VerbSystem.cs" />
|
<Compile Include="GameObjects\EntitySystems\VerbSystem.cs" />
|
||||||
<Compile Include="GameTicking\ClientGameTicker.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="Input\ContentContexts.cs" />
|
||||||
<Compile Include="Interfaces\IClientGameTicker.cs" />
|
<Compile Include="Interfaces\IClientGameTicker.cs" />
|
||||||
<Compile Include="Interfaces\IClientNotifyManager.cs" />
|
<Compile Include="Interfaces\IClientNotifyManager.cs" />
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Client.GameObjects;
|
using Content.Client.GameObjects;
|
||||||
|
using Content.Client.GameObjects.Components.Actor;
|
||||||
using Content.Client.GameObjects.Components.Clothing;
|
using Content.Client.GameObjects.Components.Clothing;
|
||||||
using Content.Client.GameObjects.Components.Construction;
|
using Content.Client.GameObjects.Components.Construction;
|
||||||
using Content.Client.GameObjects.Components.Power;
|
using Content.Client.GameObjects.Components.Power;
|
||||||
@@ -15,11 +16,13 @@ using SS14.Client;
|
|||||||
using SS14.Client.Interfaces;
|
using SS14.Client.Interfaces;
|
||||||
using SS14.Client.Interfaces.Graphics.Overlays;
|
using SS14.Client.Interfaces.Graphics.Overlays;
|
||||||
using SS14.Client.Interfaces.Input;
|
using SS14.Client.Interfaces.Input;
|
||||||
|
using SS14.Client.Player;
|
||||||
using SS14.Client.Utility;
|
using SS14.Client.Utility;
|
||||||
using SS14.Shared.ContentPack;
|
using SS14.Shared.ContentPack;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using SS14.Shared.Prototypes;
|
using SS14.Shared.Prototypes;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Content.Client
|
namespace Content.Client
|
||||||
{
|
{
|
||||||
@@ -34,7 +37,6 @@ namespace Content.Client
|
|||||||
var prototypes = IoCManager.Resolve<IPrototypeManager>();
|
var prototypes = IoCManager.Resolve<IPrototypeManager>();
|
||||||
|
|
||||||
factory.RegisterIgnore("Interactable");
|
factory.RegisterIgnore("Interactable");
|
||||||
factory.RegisterIgnore("Damageable");
|
|
||||||
factory.RegisterIgnore("Destructible");
|
factory.RegisterIgnore("Destructible");
|
||||||
factory.RegisterIgnore("Temperature");
|
factory.RegisterIgnore("Temperature");
|
||||||
factory.RegisterIgnore("PowerTransfer");
|
factory.RegisterIgnore("PowerTransfer");
|
||||||
@@ -68,15 +70,22 @@ namespace Content.Client
|
|||||||
factory.Register<ConstructorComponent>();
|
factory.Register<ConstructorComponent>();
|
||||||
factory.Register<ConstructionGhostComponent>();
|
factory.Register<ConstructionGhostComponent>();
|
||||||
factory.Register<IconSmoothComponent>();
|
factory.Register<IconSmoothComponent>();
|
||||||
|
factory.Register<DamageableComponent>();
|
||||||
factory.Register<ClothingComponent>();
|
factory.Register<ClothingComponent>();
|
||||||
factory.Register<ItemComponent>();
|
factory.Register<ItemComponent>();
|
||||||
|
|
||||||
factory.RegisterReference<ClothingComponent, ItemComponent>();
|
factory.RegisterReference<ClothingComponent, ItemComponent>();
|
||||||
|
|
||||||
|
factory.Register<SpeciesUI>();
|
||||||
|
factory.Register<CharacterInterface>();
|
||||||
|
|
||||||
factory.RegisterIgnore("Construction");
|
factory.RegisterIgnore("Construction");
|
||||||
factory.RegisterIgnore("Apc");
|
factory.RegisterIgnore("Apc");
|
||||||
factory.RegisterIgnore("Door");
|
factory.RegisterIgnore("Door");
|
||||||
factory.RegisterIgnore("PoweredLight");
|
factory.RegisterIgnore("PoweredLight");
|
||||||
factory.RegisterIgnore("Smes");
|
factory.RegisterIgnore("Smes");
|
||||||
|
factory.RegisterIgnore("Powercell");
|
||||||
|
factory.RegisterIgnore("HandheldLight");
|
||||||
|
|
||||||
prototypes.RegisterIgnore("material");
|
prototypes.RegisterIgnore("material");
|
||||||
|
|
||||||
@@ -87,6 +96,43 @@ namespace Content.Client
|
|||||||
IoCManager.BuildGraph();
|
IoCManager.BuildGraph();
|
||||||
|
|
||||||
IoCManager.Resolve<IParallaxManager>().LoadParallax();
|
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()
|
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.GameObjects;
|
||||||
using Content.Shared.Input;
|
|
||||||
using SS14.Client.GameObjects;
|
|
||||||
using SS14.Client.Interfaces.GameObjects.Components;
|
using SS14.Client.Interfaces.GameObjects.Components;
|
||||||
using SS14.Client.Interfaces.Input;
|
|
||||||
using SS14.Client.UserInterface;
|
using SS14.Client.UserInterface;
|
||||||
using SS14.Client.UserInterface.Controls;
|
using SS14.Client.UserInterface.Controls;
|
||||||
using SS14.Client.UserInterface.CustomControls;
|
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.Input;
|
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using SS14.Shared.Interfaces.Network;
|
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using SS14.Shared.Serialization;
|
using SS14.Shared.Serialization;
|
||||||
using SS14.Shared.Utility;
|
using SS14.Shared.Utility;
|
||||||
@@ -20,21 +14,36 @@ using Content.Client.GameObjects.Components.Clothing;
|
|||||||
using SS14.Shared.Interfaces.Reflection;
|
using SS14.Shared.Interfaces.Reflection;
|
||||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
||||||
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
|
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
|
||||||
|
using Content.Client.GameObjects.Components.Mobs;
|
||||||
|
using Content.Client.GameObjects.Components.Actor;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
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>();
|
private Dictionary<Slots, IEntity> _slots = new Dictionary<Slots, IEntity>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Holds the godot control for the inventory window
|
||||||
|
/// </summary>
|
||||||
private InventoryWindow _window;
|
private InventoryWindow _window;
|
||||||
|
|
||||||
private string _templateName = "HumanInventory"; //stored for serialization purposes
|
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 Inventory _inventory;
|
||||||
|
|
||||||
private ISpriteComponent _sprite;
|
private ISpriteComponent _sprite;
|
||||||
|
|
||||||
|
//Relevant interface implementation for the character UI controller
|
||||||
|
public Control Scene => _window;
|
||||||
|
public UIPriority Priority => UIPriority.Inventory;
|
||||||
|
|
||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
@@ -42,22 +51,17 @@ namespace Content.Client.GameObjects
|
|||||||
_window.Dispose();
|
_window.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnAdd()
|
|
||||||
{
|
|
||||||
base.OnAdd();
|
|
||||||
|
|
||||||
_openMenuCmdHandler = InputCmdHandler.FromDelegate(session => { _window.AddToScreen(); _window.Open(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
|
//Loads inventory template
|
||||||
var reflectionManager = IoCManager.Resolve<IReflectionManager>();
|
var reflectionManager = IoCManager.Resolve<IReflectionManager>();
|
||||||
var type = reflectionManager.LooseGetType(_templateName);
|
var type = reflectionManager.LooseGetType(_templateName);
|
||||||
DebugTools.Assert(type != null);
|
DebugTools.Assert(type != null);
|
||||||
_inventory = (Inventory)Activator.CreateInstance(type);
|
_inventory = (Inventory)Activator.CreateInstance(type);
|
||||||
|
|
||||||
|
//Creates godot control class for inventory
|
||||||
_window = new InventoryWindow(this);
|
_window = new InventoryWindow(this);
|
||||||
_window.CreateInventory(_inventory);
|
_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)
|
private void _setSlot(Slots slot, IEntity entity)
|
||||||
{
|
{
|
||||||
if (_sprite != null && entity.TryGetComponent(out ClothingComponent clothing))
|
if (_sprite != null && entity.TryGetComponent(out ClothingComponent clothing))
|
||||||
@@ -178,7 +167,7 @@ namespace Content.Client.GameObjects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Temporary window to hold the basis for inventory hud
|
/// Temporary window to hold the basis for inventory hud
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private class InventoryWindow : SS14Window
|
private class InventoryWindow : Control
|
||||||
{
|
{
|
||||||
private int elements_x;
|
private int elements_x;
|
||||||
|
|
||||||
@@ -187,13 +176,11 @@ namespace Content.Client.GameObjects
|
|||||||
private Dictionary<Slots, InventoryButton> InventorySlots = new Dictionary<Slots, InventoryButton>(); //ordered dictionary?
|
private Dictionary<Slots, InventoryButton> InventorySlots = new Dictionary<Slots, InventoryButton>(); //ordered dictionary?
|
||||||
private ClientInventoryComponent InventoryComponent;
|
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)
|
public InventoryWindow(ClientInventoryComponent inventory)
|
||||||
{
|
{
|
||||||
InventoryComponent = inventory;
|
InventoryComponent = inventory;
|
||||||
|
|
||||||
HideOnClose = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -203,7 +190,7 @@ namespace Content.Client.GameObjects
|
|||||||
{
|
{
|
||||||
elements_x = inventory.Columns;
|
elements_x = inventory.Columns;
|
||||||
|
|
||||||
GridContainer = (GridContainer)Contents.GetChild("PanelContainer").GetChild("CenterContainer").GetChild("GridContainer");
|
GridContainer = (GridContainer)GetChild("CenterContainer").GetChild("GridContainer");
|
||||||
GridContainer.Columns = elements_x;
|
GridContainer.Columns = elements_x;
|
||||||
IndexedSlots = new List<Slots>(inventory.SlotMasks);
|
IndexedSlots = new List<Slots>(inventory.SlotMasks);
|
||||||
|
|
||||||
@@ -304,7 +291,7 @@ namespace Content.Client.GameObjects
|
|||||||
public Slots Slot;
|
public Slots Slot;
|
||||||
public EntityUid EntityUid;
|
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)
|
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="Administration\AGhost.cs" />
|
||||||
<Compile Include="AI\AimShootLifeProcessor.cs" />
|
<Compile Include="AI\AimShootLifeProcessor.cs" />
|
||||||
<Compile Include="EntryPoint.cs" />
|
<Compile Include="EntryPoint.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Damage\DamageThreshold.cs" />
|
||||||
<Compile Include="GameObjects\Components\Doors\ServerDoorComponent.cs" />
|
<Compile Include="GameObjects\Components\Doors\ServerDoorComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Interactable\HandheldLightComponent.cs" />
|
<Compile Include="GameObjects\Components\Interactable\HandheldLightComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Interactable\Tools\BaseTool.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\StoreableComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Items\Storage\ServerStorageComponent.cs" />
|
<Compile Include="GameObjects\Components\Items\Storage\ServerStorageComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Items\Storage\ItemComponent.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\MindComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Mobs\SpeciesComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Power\PowerCellComponent.cs" />
|
<Compile Include="GameObjects\Components\Power\PowerCellComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Power\PowerStorageComponent.cs" />
|
<Compile Include="GameObjects\Components\Power\PowerStorageComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Power\PowerGeneratorComponent.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\Projectile\ProjectileWeapon.cs" />
|
||||||
<Compile Include="GameObjects\Components\Weapon\Ranged\RangedWeapon.cs" />
|
<Compile Include="GameObjects\Components\Weapon\Ranged\RangedWeapon.cs" />
|
||||||
<Compile Include="GameObjects\ContainerSlot.cs" />
|
<Compile Include="GameObjects\ContainerSlot.cs" />
|
||||||
|
<Compile Include="GameObjects\EntitySystems\ActionBlockerSystem.cs" />
|
||||||
<Compile Include="GameObjects\EntitySystems\Click\ExamineSystem.cs" />
|
<Compile Include="GameObjects\EntitySystems\Click\ExamineSystem.cs" />
|
||||||
<Compile Include="GameObjects\EntitySystems\Click\InteractionSystem.cs" />
|
<Compile Include="GameObjects\EntitySystems\Click\InteractionSystem.cs" />
|
||||||
<Compile Include="GameObjects\EntitySystems\DoorSystem.cs" />
|
<Compile Include="GameObjects\EntitySystems\DoorSystem.cs" />
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ namespace Content.Server
|
|||||||
factory.RegisterIgnore("ConstructionGhost");
|
factory.RegisterIgnore("ConstructionGhost");
|
||||||
|
|
||||||
factory.Register<MindComponent>();
|
factory.Register<MindComponent>();
|
||||||
|
factory.Register<SpeciesComponent>();
|
||||||
|
|
||||||
IoCManager.Register<ISharedNotifyManager, ServerNotifyManager>();
|
IoCManager.Register<ISharedNotifyManager, ServerNotifyManager>();
|
||||||
IoCManager.Register<IServerNotifyManager, 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,
|
/// A component that handles receiving damage and healing,
|
||||||
/// as well as informing other components of it.
|
/// as well as informing other components of it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DamageableComponent : Component, IDamageableComponent
|
public class DamageableComponent : SharedDamageableComponent, IDamageableComponent
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string Name => "Damageable";
|
public override string Name => "Damageable";
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override uint? NetID => ContentNetIDs.DAMAGEABLE;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The resistance set of this object.
|
/// The resistance set of this object.
|
||||||
/// Affects receiving damage of various types.
|
/// Affects receiving damage of various types.
|
||||||
@@ -33,11 +30,17 @@ namespace Content.Server.GameObjects
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public ResistanceSet Resistances { get; private set; }
|
public ResistanceSet Resistances { get; private set; }
|
||||||
|
|
||||||
Dictionary<DamageType, int> CurrentDamage = new Dictionary<DamageType, int>();
|
public IReadOnlyDictionary<DamageType, int> CurrentDamage => _currentDamage;
|
||||||
Dictionary<DamageType, List<int>> Thresholds = new Dictionary<DamageType, List<int>>();
|
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 event EventHandler<DamageThresholdPassedEventArgs> DamageThresholdPassed;
|
||||||
|
|
||||||
|
public override ComponentState GetComponentState()
|
||||||
|
{
|
||||||
|
return new DamageComponentState(_currentDamage);
|
||||||
|
}
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
{
|
{
|
||||||
@@ -55,9 +58,10 @@ namespace Content.Server.GameObjects
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
InitializeDamageType(DamageType.Total);
|
InitializeDamageType(DamageType.Total);
|
||||||
if (Owner is IOnDamageBehavior damageBehavior)
|
|
||||||
|
foreach (var damagebehavior in Owner.GetAllComponents<IOnDamageBehavior>())
|
||||||
{
|
{
|
||||||
AddThresholdsFrom(damageBehavior);
|
AddThresholdsFrom(damagebehavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecalculateComponentThresholds();
|
RecalculateComponentThresholds();
|
||||||
@@ -72,7 +76,7 @@ namespace Content.Server.GameObjects
|
|||||||
}
|
}
|
||||||
InitializeDamageType(damageType);
|
InitializeDamageType(damageType);
|
||||||
|
|
||||||
int oldValue = CurrentDamage[damageType];
|
int oldValue = _currentDamage[damageType];
|
||||||
int oldTotalValue = -1;
|
int oldTotalValue = -1;
|
||||||
|
|
||||||
if (amount == 0)
|
if (amount == 0)
|
||||||
@@ -81,13 +85,13 @@ namespace Content.Server.GameObjects
|
|||||||
}
|
}
|
||||||
|
|
||||||
amount = Resistances.CalculateDamage(damageType, amount);
|
amount = Resistances.CalculateDamage(damageType, amount);
|
||||||
CurrentDamage[damageType] = Math.Max(0, CurrentDamage[damageType] + amount);
|
_currentDamage[damageType] = Math.Max(0, _currentDamage[damageType] + amount);
|
||||||
UpdateForDamageType(damageType, oldValue);
|
UpdateForDamageType(damageType, oldValue);
|
||||||
|
|
||||||
if (Resistances.AppliesToTotal(damageType))
|
if (Resistances.AppliesToTotal(damageType))
|
||||||
{
|
{
|
||||||
oldTotalValue = CurrentDamage[DamageType.Total];
|
oldTotalValue = _currentDamage[DamageType.Total];
|
||||||
CurrentDamage[DamageType.Total] = Math.Max(0, CurrentDamage[DamageType.Total] + amount);
|
_currentDamage[DamageType.Total] = Math.Max(0, _currentDamage[DamageType.Total] + amount);
|
||||||
UpdateForDamageType(DamageType.Total, oldTotalValue);
|
UpdateForDamageType(DamageType.Total, oldTotalValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +108,7 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
void UpdateForDamageType(DamageType damageType, int oldValue)
|
void UpdateForDamageType(DamageType damageType, int oldValue)
|
||||||
{
|
{
|
||||||
int change = CurrentDamage[damageType] - oldValue;
|
int change = _currentDamage[damageType] - oldValue;
|
||||||
|
|
||||||
if (change == 0)
|
if (change == 0)
|
||||||
{
|
{
|
||||||
@@ -113,11 +117,12 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
int changeSign = Math.Sign(change);
|
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);
|
DamageThresholdPassed?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,62 +147,23 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
foreach (DamageThreshold threshold in thresholds)
|
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)
|
void InitializeDamageType(DamageType damageType)
|
||||||
{
|
{
|
||||||
if (!CurrentDamage.ContainsKey(damageType))
|
if (!_currentDamage.ContainsKey(damageType))
|
||||||
{
|
{
|
||||||
CurrentDamage.Add(damageType, 0);
|
_currentDamage.Add(damageType, 0);
|
||||||
Thresholds.Add(damageType, new List<int>());
|
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("thresholdtype", DamageType.Total, type => damageType = type);
|
||||||
serializer.DataReadFunction("thresholdvalue", 0, val => damageValue = val);
|
serializer.DataReadFunction("thresholdvalue", 0, val => damageValue = val);
|
||||||
|
|
||||||
Threshold = new DamageThreshold(damageType, damageValue);
|
Threshold = new DamageThreshold(damageType, damageValue, ThresholdType.Destruction);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
if (Owner.TryGetComponent<DamageableComponent>(out DamageableComponent damageable))
|
|
||||||
{
|
|
||||||
damageable.DamageThresholdPassed += OnDamageThresholdPassed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,9 @@
|
|||||||
using System;
|
using Content.Shared.GameObjects;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects
|
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>
|
/// <summary>
|
||||||
/// Resistance set used by damageable objects.
|
/// Resistance set used by damageable objects.
|
||||||
/// For each damage type, has a coefficient, damage reduction and "included in total" value.
|
/// 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 System.Collections.Generic;
|
||||||
using YamlDotNet.RepresentationModel;
|
using YamlDotNet.RepresentationModel;
|
||||||
using SS14.Shared.Utility;
|
using SS14.Shared.Utility;
|
||||||
|
using Content.Shared.GameObjects;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Projectiles
|
namespace Content.Server.GameObjects.Components.Projectiles
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.Components.Projectiles;
|
using Content.Server.GameObjects.Components.Projectiles;
|
||||||
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using SS14.Shared.Interfaces.Timing;
|
|||||||
using SS14.Shared.GameObjects.EntitySystemMessages;
|
using SS14.Shared.GameObjects.EntitySystemMessages;
|
||||||
using SS14.Shared.Serialization;
|
using SS14.Shared.Serialization;
|
||||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Content.Shared.GameObjects;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Weapon.Melee
|
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.Audio;
|
||||||
using SS14.Shared.GameObjects.EntitySystemMessages;
|
using SS14.Shared.GameObjects.EntitySystemMessages;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
@@ -9,6 +10,7 @@ using SS14.Shared.IoC;
|
|||||||
using SS14.Shared.Map;
|
using SS14.Shared.Map;
|
||||||
using SS14.Shared.Maths;
|
using SS14.Shared.Maths;
|
||||||
using SS14.Shared.Physics;
|
using SS14.Shared.Physics;
|
||||||
|
using SS14.Shared.Serialization;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
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;
|
private const float MaxLength = 20;
|
||||||
public override string Name => "HitscanWeapon";
|
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)
|
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))
|
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 offset = angle.ToVec() * dist / 2;
|
||||||
var message = new EffectSystemMessage
|
var message = new EffectSystemMessage
|
||||||
{
|
{
|
||||||
EffectSprite = SpriteName,
|
EffectSprite = Spritename,
|
||||||
Born = time,
|
Born = time,
|
||||||
DeathTime = time + TimeSpan.FromSeconds(1),
|
DeathTime = time + TimeSpan.FromSeconds(1),
|
||||||
Size = new Vector2(dist, 1f),
|
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;
|
var item = hands.GetActiveHand?.Owner;
|
||||||
|
|
||||||
if (!MobCanInteract(player))
|
if (!ActionBlockerSystem.CanInteract(player))
|
||||||
return;
|
return;
|
||||||
//TODO: Mob status code that allows or rejects interactions based on current mob status
|
//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
|
||||||
//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
|
//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>
|
/// <summary>
|
||||||
/// We didn't click on any entity, try doing an afterattack on the click location
|
/// We didn't click on any entity, try doing an afterattack on the click location
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -324,7 +314,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
/// <param name="used"></param>
|
/// <param name="used"></param>
|
||||||
public static void TryUseInteraction(IEntity user, IEntity used)
|
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);
|
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 SS14.Shared.Interfaces.GameObjects;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="EntryPoint.cs" />
|
<Compile Include="EntryPoint.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Damage\DamageableComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Inventory\EquipmentSlotDefinitions.cs" />
|
<Compile Include="GameObjects\Components\Inventory\EquipmentSlotDefinitions.cs" />
|
||||||
<Compile Include="GameObjects\Components\Inventory\InventoryTemplates.cs" />
|
<Compile Include="GameObjects\Components\Inventory\InventoryTemplates.cs" />
|
||||||
<Compile Include="GameObjects\Components\Inventory\SharedInventoryComponent.cs" />
|
<Compile Include="GameObjects\Components\Inventory\SharedInventoryComponent.cs" />
|
||||||
@@ -71,6 +72,7 @@
|
|||||||
<Compile Include="GameObjects\Components\Storage\SharedStorageComponent.cs" />
|
<Compile Include="GameObjects\Components\Storage\SharedStorageComponent.cs" />
|
||||||
<Compile Include="GameObjects\ContentNetIDs.cs" />
|
<Compile Include="GameObjects\ContentNetIDs.cs" />
|
||||||
<Compile Include="GameObjects\EntitySystemMessages\VerbSystemMessages.cs" />
|
<Compile Include="GameObjects\EntitySystemMessages\VerbSystemMessages.cs" />
|
||||||
|
<Compile Include="GameObjects\Messages\Mob\HealthHud.cs" />
|
||||||
<Compile Include="GameObjects\PhysicalConstants.cs" />
|
<Compile Include="GameObjects\PhysicalConstants.cs" />
|
||||||
<Compile Include="Interfaces\ISharedNotifyManager.cs" />
|
<Compile Include="Interfaces\ISharedNotifyManager.cs" />
|
||||||
<Compile Include="GameObjects\Verb.cs" />
|
<Compile Include="GameObjects\Verb.cs" />
|
||||||
@@ -117,4 +119,4 @@
|
|||||||
<Compile Include="Construction\ConstructionPrototype.cs" />
|
<Compile Include="Construction\ConstructionPrototype.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<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 INVENTORY = 1006;
|
||||||
public const uint POWER_DEBUG_TOOL = 1007;
|
public const uint POWER_DEBUG_TOOL = 1007;
|
||||||
public const uint CONSTRUCTOR = 1008;
|
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
|
- type: Input
|
||||||
context: "human"
|
context: "human"
|
||||||
|
|
||||||
|
- type: Species
|
||||||
|
Template: Human
|
||||||
|
- type: Damageable
|
||||||
|
|
||||||
- type: Eye
|
- type: Eye
|
||||||
zoom: 0.5, 0.5
|
zoom: 0.5, 0.5
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
sprite: Objects/laser_retro.rsi
|
sprite: Objects/laser_retro.rsi
|
||||||
state: 100
|
state: 100
|
||||||
- type: HitscanWeapon
|
- type: HitscanWeapon
|
||||||
|
damage: 30
|
||||||
|
sprite: "Objects/laser.png"
|
||||||
- type: Item
|
- type: Item
|
||||||
Size: 24
|
Size: 24
|
||||||
sprite: Objects/laser_retro.rsi
|
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="PanelContainer" type="PanelContainer"]
|
||||||
|
|
||||||
[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"]
|
|
||||||
|
|
||||||
anchor_left = 0.0
|
anchor_left = 0.0
|
||||||
anchor_top = 0.0
|
anchor_top = 0.0
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 0.0
|
||||||
|
margin_bottom = 400.0
|
||||||
rect_pivot_offset = Vector2( 0, 0 )
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
rect_clip_content = false
|
rect_clip_content = false
|
||||||
mouse_filter = 0
|
mouse_filter = 0
|
||||||
@@ -25,7 +15,7 @@ size_flags_horizontal = 3
|
|||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
_sections_unfolded = [ "Anchor", "Grow Direction", "Margin", "Mouse", "Rect", "Size Flags", "Theme" ]
|
_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_left = 0.0
|
||||||
anchor_top = 0.0
|
anchor_top = 0.0
|
||||||
@@ -33,8 +23,8 @@ anchor_right = 0.0
|
|||||||
anchor_bottom = 0.0
|
anchor_bottom = 0.0
|
||||||
margin_left = 7.0
|
margin_left = 7.0
|
||||||
margin_top = 7.0
|
margin_top = 7.0
|
||||||
margin_right = 276.0
|
margin_right = 1017.0
|
||||||
margin_bottom = 424.0
|
margin_bottom = 393.0
|
||||||
rect_pivot_offset = Vector2( 0, 0 )
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
rect_clip_content = false
|
rect_clip_content = false
|
||||||
mouse_filter = 0
|
mouse_filter = 0
|
||||||
@@ -44,16 +34,16 @@ size_flags_vertical = 1
|
|||||||
use_top_left = false
|
use_top_left = false
|
||||||
_sections_unfolded = [ "Anchor", "Focus", "Grow Direction", "Hint", "Margin", "Mouse", "Rect", "Size Flags", "Theme" ]
|
_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_left = 0.0
|
||||||
anchor_top = 0.0
|
anchor_top = 0.0
|
||||||
anchor_right = 0.0
|
anchor_right = 0.0
|
||||||
anchor_bottom = 0.0
|
anchor_bottom = 0.0
|
||||||
margin_left = 134.0
|
margin_left = 505.0
|
||||||
margin_top = 208.0
|
margin_top = 193.0
|
||||||
margin_right = 134.0
|
margin_right = 505.0
|
||||||
margin_bottom = 208.0
|
margin_bottom = 193.0
|
||||||
rect_pivot_offset = Vector2( 0, 0 )
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
rect_clip_content = false
|
rect_clip_content = false
|
||||||
mouse_filter = 0
|
mouse_filter = 0
|
||||||
@@ -63,17 +53,4 @@ size_flags_vertical = 1
|
|||||||
columns = 3
|
columns = 3
|
||||||
_sections_unfolded = [ "Anchor", "Focus", "Grow Direction", "Hint", "Margin", "Material", "Mouse", "Rect", "Size Flags", "Theme", "custom_constants" ]
|
_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 |