Adds IThrown, ILand interfaces. Adds dice. (#273)
* Dice, IThrown, ILand * Adds sounds to the dice using a sound collection. * Seed random instance better. * Missed a ")", should compile now
This commit is contained in:
committed by
Pieter-Jan Briers
parent
92668432a7
commit
d9077bde74
@@ -430,6 +430,18 @@ namespace Content.Server.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
public bool ThrowItem()
|
||||
{
|
||||
var item = GetActiveHand?.Owner;
|
||||
if (item != null)
|
||||
{
|
||||
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
||||
return interactionSystem.TryThrowInteraction(Owner, item);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
|
||||
IComponent component = null)
|
||||
{
|
||||
|
||||
101
Content.Server/GameObjects/Components/Items/DiceComponent.cs
Normal file
101
Content.Server/GameObjects/Components/Items/DiceComponent.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using Content.Server.GameObjects.Components.Sound;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Shared.Audio;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Items
|
||||
{
|
||||
public class DiceComponent : Component, IActivate, IUse, ILand, IExamine
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
||||
#pragma warning restore 649
|
||||
|
||||
public override string Name => "Dice";
|
||||
|
||||
private Random _random;
|
||||
private int _step = 1;
|
||||
private int _sides = 20;
|
||||
private int _currentSide = 20;
|
||||
[ViewVariables]
|
||||
public string _soundCollectionName = "dice";
|
||||
[ViewVariables]
|
||||
public int Step => _step;
|
||||
[ViewVariables]
|
||||
public int Sides => _sides;
|
||||
[ViewVariables]
|
||||
public int CurrentSide => _currentSide;
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
serializer.DataField(ref _step, "step", 1);
|
||||
serializer.DataField(ref _sides, "sides", 20);
|
||||
serializer.DataField(ref _soundCollectionName, "diceSoundCollection", "dice");
|
||||
_currentSide = _sides;
|
||||
}
|
||||
|
||||
public override void OnAdd()
|
||||
{
|
||||
base.OnAdd();
|
||||
_random = new Random(Owner.Uid.GetHashCode() ^ DateTime.Now.GetHashCode());
|
||||
}
|
||||
|
||||
public void Roll()
|
||||
{
|
||||
_currentSide = _random.Next(1, (_sides/_step)+1) * _step;
|
||||
if (!Owner.TryGetComponent(out SpriteComponent sprite)) return;
|
||||
sprite.LayerSetState(0, $"d{_sides}{_currentSide}");
|
||||
PlayDiceEffect();
|
||||
}
|
||||
|
||||
public void PlayDiceEffect()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_soundCollectionName))
|
||||
{
|
||||
var soundCollection = _prototypeManager.Index<SoundCollectionPrototype>(_soundCollectionName);
|
||||
var file = _random.Pick(soundCollection.PickFiles);
|
||||
Owner.GetComponent<SoundComponent>().Play(file, AudioParams.Default);
|
||||
}
|
||||
}
|
||||
|
||||
public void Activate(ActivateEventArgs eventArgs)
|
||||
{
|
||||
Roll();
|
||||
}
|
||||
|
||||
public bool UseEntity(UseEntityEventArgs eventArgs)
|
||||
{
|
||||
Roll();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Land(LandEventArgs eventArgs)
|
||||
{
|
||||
Roll();
|
||||
}
|
||||
|
||||
public void Examine(FormattedMessage message)
|
||||
{
|
||||
message.AddText("A dice with ");
|
||||
message.PushColor(new Color(1F, 0.75F, 0.75F));
|
||||
message.AddText(_sides.ToString());
|
||||
message.Pop();
|
||||
message.AddText(" sides.\nIt has landed on a ");
|
||||
message.PushColor(new Color(1F, 1F, 1F));
|
||||
message.AddText(_currentSide.ToString());
|
||||
message.Pop();
|
||||
message.AddText(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,11 @@ namespace Content.Server.GameObjects
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanThrow()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -77,6 +82,11 @@ namespace Content.Server.GameObjects
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanThrow()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -118,5 +128,10 @@ namespace Content.Server.GameObjects
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanThrow()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,11 @@ namespace Content.Server.GameObjects
|
||||
return CurrentDamageState.CanUse();
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanThrow()
|
||||
{
|
||||
return CurrentDamageState.CanThrow();
|
||||
}
|
||||
|
||||
List<DamageThreshold> IOnDamageBehavior.GetAllDamageThresholds()
|
||||
{
|
||||
var thresholdlist = DamageTemplate.DamageThresholds;
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Projectiles;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.Physics;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.GameObjects.Components
|
||||
{
|
||||
class ThrownItemComponent : ProjectileComponent, ICollideBehavior
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
||||
#pragma warning restore 649
|
||||
|
||||
public override string Name => "ThrownItem";
|
||||
|
||||
/// <summary>
|
||||
/// User who threw the item.
|
||||
/// </summary>
|
||||
public IEntity User;
|
||||
|
||||
void ICollideBehavior.CollideWith(List<IEntity> collidedwith)
|
||||
{
|
||||
foreach (var entity in collidedwith)
|
||||
@@ -31,9 +43,13 @@ namespace Content.Server.GameObjects.Components
|
||||
body.CollisionMask &= (int)~CollisionGroup.Mob;
|
||||
body.IsScrapingFloor = true;
|
||||
|
||||
// KYS, your job is finished.
|
||||
// KYS, your job is finished. Trigger ILand as well.
|
||||
Owner.RemoveComponent<ThrownItemComponent>();
|
||||
_entitySystemManager.GetEntitySystem<InteractionSystem>().LandInteraction(User, Owner, Owner.Transform.GridPosition);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
bool CanInteract();
|
||||
|
||||
bool CanUse();
|
||||
|
||||
bool CanThrow();
|
||||
}
|
||||
|
||||
public class ActionBlockerSystem : EntitySystem
|
||||
@@ -43,5 +45,15 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
}
|
||||
return canuse;
|
||||
}
|
||||
|
||||
public static bool CanThrow(IEntity entity)
|
||||
{
|
||||
bool canthrow = true;
|
||||
foreach (var actionblockercomponents in entity.GetAllComponents<IActionBlocker>())
|
||||
{
|
||||
canthrow &= actionblockercomponents.CanThrow();
|
||||
}
|
||||
return canthrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,44 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
public IEntity User { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface gives components behavior when thrown.
|
||||
/// </summary>
|
||||
public interface IThrown
|
||||
{
|
||||
void Thrown(ThrownEventArgs eventArgs);
|
||||
}
|
||||
|
||||
public class ThrownEventArgs : EventArgs
|
||||
{
|
||||
public ThrownEventArgs(IEntity user)
|
||||
{
|
||||
User = user;
|
||||
}
|
||||
|
||||
public IEntity User { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface gives components behavior when landing after being thrown.
|
||||
/// </summary>
|
||||
public interface ILand
|
||||
{
|
||||
void Land(LandEventArgs eventArgs);
|
||||
}
|
||||
|
||||
public class LandEventArgs : EventArgs
|
||||
{
|
||||
public LandEventArgs(IEntity user, GridCoordinates landingLocation)
|
||||
{
|
||||
User = user;
|
||||
LandingLocation = landingLocation;
|
||||
}
|
||||
|
||||
public IEntity User { get; }
|
||||
public GridCoordinates LandingLocation { get; }
|
||||
}
|
||||
|
||||
public interface IAttack
|
||||
{
|
||||
void Attack(AttackEventArgs eventArgs);
|
||||
@@ -462,6 +500,63 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activates the Use behavior of an object
|
||||
/// Verifies that the user is capable of doing the use interaction first
|
||||
/// </summary>
|
||||
public bool TryThrowInteraction(IEntity user, IEntity item)
|
||||
{
|
||||
if (user == null || item == null || !ActionBlockerSystem.CanThrow(user)) return false;
|
||||
|
||||
ThrownInteraction(user, item);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Thrown on all components that implement the IThrown interface
|
||||
/// on an entity that has been thrown.
|
||||
/// </summary>
|
||||
public void ThrownInteraction(IEntity user, IEntity thrown)
|
||||
{
|
||||
var throwMsg = new ThrownMessage(user, thrown);
|
||||
RaiseEvent(throwMsg);
|
||||
if (throwMsg.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var comps = thrown.GetAllComponents<IThrown>().ToList();
|
||||
|
||||
// Call Thrown on all components that implement the interface
|
||||
foreach (var comp in comps)
|
||||
{
|
||||
comp.Thrown(new ThrownEventArgs(user));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Land on all components that implement the ILand interface
|
||||
/// on an entity that has landed after being thrown.
|
||||
/// </summary>
|
||||
public void LandInteraction(IEntity user, IEntity landing, GridCoordinates landLocation)
|
||||
{
|
||||
var landMsg = new LandMessage(user, landing, landLocation);
|
||||
RaiseEvent(landMsg);
|
||||
if (landMsg.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var comps = landing.GetAllComponents<ILand>().ToList();
|
||||
|
||||
// Call Land on all components that implement the interface
|
||||
foreach (var comp in comps)
|
||||
{
|
||||
comp.Land(new LandEventArgs(user, landLocation));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will have two behaviors, either "uses" the weapon at range on the entity if it is capable of accepting that action
|
||||
/// Or it will use the weapon itself on the position clicked, regardless of what was there
|
||||
@@ -715,6 +810,68 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when throwing the entity in your hands.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public class ThrownMessage : EntitySystemMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// If this message has already been "handled" by a previous system.
|
||||
/// </summary>
|
||||
public bool Handled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Entity that threw the item.
|
||||
/// </summary>
|
||||
public IEntity User { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Item that was thrown.
|
||||
/// </summary>
|
||||
public IEntity Thrown { get; }
|
||||
|
||||
public ThrownMessage(IEntity user, IEntity thrown)
|
||||
{
|
||||
User = user;
|
||||
Thrown = thrown;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when an entity that was thrown lands.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public class LandMessage : EntitySystemMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// If this message has already been "handled" by a previous system.
|
||||
/// </summary>
|
||||
public bool Handled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Entity that threw the item.
|
||||
/// </summary>
|
||||
public IEntity User { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Item that was thrown.
|
||||
/// </summary>
|
||||
public IEntity Thrown { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Location where the item landed.
|
||||
/// </summary>
|
||||
public GridCoordinates LandLocation { get; }
|
||||
|
||||
public LandMessage(IEntity user, IEntity thrown, GridCoordinates landLocation)
|
||||
{
|
||||
User = user;
|
||||
Thrown = thrown;
|
||||
LandLocation = landLocation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when an entity is activated in the world.
|
||||
/// </summary>
|
||||
|
||||
@@ -135,6 +135,9 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
|
||||
var throwEnt = handsComp.GetHand(handsComp.ActiveIndex).Owner;
|
||||
|
||||
if (!handsComp.ThrowItem())
|
||||
return;
|
||||
|
||||
// pop off an item, or throw the single item in hand.
|
||||
if (!throwEnt.TryGetComponent(out StackComponent stackComp) || stackComp.Count < 2)
|
||||
{
|
||||
@@ -147,9 +150,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
}
|
||||
|
||||
if (!throwEnt.TryGetComponent(out CollidableComponent colComp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
colComp.CollisionEnabled = true;
|
||||
// I can now collide with player, so that i can do damage.
|
||||
@@ -161,15 +162,14 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
colComp.IsScrapingFloor = false;
|
||||
}
|
||||
|
||||
projComp.User = plyEnt;
|
||||
projComp.IgnoreEntity(plyEnt);
|
||||
|
||||
var transform = plyEnt.Transform;
|
||||
var dirVec = (coords.ToWorld(_mapManager).Position - transform.WorldPosition).Normalized;
|
||||
|
||||
if (!throwEnt.TryGetComponent(out PhysicsComponent physComp))
|
||||
{
|
||||
physComp = throwEnt.AddComponent<PhysicsComponent>();
|
||||
}
|
||||
|
||||
// TODO: Move this into PhysicsSystem, we need an ApplyForce function.
|
||||
var a = ThrowForce / (float) Math.Max(0.001, physComp.Mass); // a = f / m
|
||||
@@ -185,6 +185,8 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
|
||||
lHomoDir.Normalize();
|
||||
transform.LocalRotation = new Angle(lHomoDir.Xy);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user