GUNS GUNS GUNS

GUESS WHAT
This commit is contained in:
Reinier Vens 2021-01-05 02:56:17 +00:00
commit 8aaccac2b5
83 changed files with 15291 additions and 1291 deletions

View file

@ -0,0 +1,74 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
using System;
using MessagePack;
using Newtonsoft.Json;
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
public class ConstantWeaponData : WeaponData
{
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
{
return new ConstantWeapon(context, this, entity, item);
}
}
public class ConstantWeapon : IBehavior, IAlwaysUpdatedBehavior
{
private ConstantWeaponData _data;
public int _burstCount;
public float _burstTimer;
private Entity Entity { get; }
private EquippedItem Item { get; }
private ItemManager Context { get; }
public BehaviorData Data => _data;
public event Action OnStartFiring;
public event Action OnStopFiring;
private bool _firing;
private bool _stoppedFiring;
public ConstantWeapon(ItemManager context, ConstantWeaponData c, Entity entity, EquippedItem item)
{
Context = context;
_data = c;
Entity = entity;
Item = item;
}
public bool Update(float delta)
{
if (!_firing)
{
_firing = true;
OnStartFiring?.Invoke();
}
_stoppedFiring = false;
return true;
}
public void AlwaysUpdate(float delta)
{
// Update executes after AlwaysUpdate,
// so if the stop flag didn't get disabled previous frame,
// we know the weapon has stopped firing
if (_firing)
{
if (_stoppedFiring)
{
_firing = false;
_stoppedFiring = false;
OnStopFiring?.Invoke();
}
else
_stoppedFiring = true;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f437aa69c4d96524cbe4caedd16678b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -7,11 +7,8 @@ using Newtonsoft.Json;
using Unity.Mathematics;
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
public class LauncherData : WeaponData
public class LauncherData : InstantWeaponData
{
[InspectablePrefab, JsonProperty("missile"), Key(6)]
public string MissilePrefab;
[InspectableAnimationCurve, JsonProperty("guidance"), Key(7)]
public float4[] GuidanceCurve;
@ -41,7 +38,7 @@ public class LauncherData : WeaponData
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
{
return new Launcher(context, this, entity, item);
return new InstantWeapon(context, this, entity, item);
}
}

View file

@ -2,15 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
using System;
using MessagePack;
using Newtonsoft.Json;
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
public class ProjectileWeaponData : WeaponData
public class ProjectileWeaponData : InstantWeaponData
{
[InspectablePrefab, JsonProperty("bullet"), Key(6)]
public string BulletPrefab;
[InspectableField, JsonProperty("spread"), Key(7)]
public PerformanceStat Spread = new PerformanceStat();
@ -22,46 +20,6 @@ public class ProjectileWeaponData : WeaponData
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
{
return new ProjectileWeapon(context, this, entity, item);
}
}
public class ProjectileWeapon : IBehavior
{
private ProjectileWeaponData _data;
private Entity Entity { get; }
private EquippedItem Item { get; }
private ItemManager Context { get; }
public BehaviorData Data => _data;
public ProjectileWeapon(ItemManager context, ProjectileWeaponData c, Entity entity, EquippedItem item)
{
Context = context;
_data = c;
Entity = entity;
Item = item;
}
// private void Fire()
// {
// Hardpoint.Temperature += _projectileWeapon.Heat.Evaluate(Hardpoint) / Hardpoint.HeatCapacity;
// var inst = GameObject.Instantiate(_projectileWeapon.BulletPrefab).transform;
// Physics.IgnoreCollision(Hardpoint.Ship.Ship.GetComponent<Collider>(), inst.GetComponent<Collider>());
// var bullet = inst.GetComponent<Bullet>();
// bullet.Target = Hardpoint.Ship.Ship.Target;
// bullet.Source = Hardpoint.Ship.Ship.Hitpoints;
// bullet.Lifetime = _projectileWeapon.Range.Evaluate(Hardpoint) / _projectileWeapon.Velocity.Evaluate(Hardpoint);
// bullet.Damage = _projectileWeapon.Damage.Evaluate(Hardpoint);
// inst.position = Hardpoint.Proxy.position;
// inst.rotation = Hardpoint.Proxy.rotation;
// inst.GetComponent<Rigidbody>().velocity = _projectileWeapon.Velocity.Evaluate(Hardpoint) * Vector3.RotateTowards(-inst.forward, Hardpoint.Ship.Ship.Direction, _projectileWeapon.Deflection * Mathf.Deg2Rad, 1);
// Hardpoint.Ship.Ship.AudioSource.PlayOneShot(_projectileWeapon.Sounds.RandomElement());
// Debug.Log($"Firing bullet {b}");
// }
public bool Update(float delta)
{
return true;
return new InstantWeapon(context, this, entity, item);
}
}

View file

@ -51,8 +51,11 @@ public class Visibility : IBehavior, IAlwaysUpdatedBehavior
public void AlwaysUpdate(float delta)
{
// TODO: Time independent decay?
Entity.VisibilitySources[this] *= Context.Evaluate(_data.VisibilityDecay, Item.EquippableItem, Entity);
if (Entity.VisibilitySources[this] < 0.01f) Entity.VisibilitySources.Remove(this);
if(Entity.VisibilitySources.ContainsKey(this))
{
Entity.VisibilitySources[this] *= Context.Evaluate(_data.VisibilityDecay, Item.EquippableItem, Entity);
if (Entity.VisibilitySources[this] < 0.01f) Entity.VisibilitySources.Remove(this);
}
}
}

View file

@ -2,11 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
using System;
using MessagePack;
using Newtonsoft.Json;
[Union(0, typeof(ProjectileWeaponData)),
Union(1, typeof(LauncherData))]
Union(1, typeof(LauncherData)),
Union(2, typeof(ConstantWeaponData))]
public abstract class WeaponData : BehaviorData
{
[InspectableField, JsonProperty("damageType"), Key(1)]
@ -17,10 +19,93 @@ public abstract class WeaponData : BehaviorData
[InspectableField, JsonProperty("range"), Key(3)]
public PerformanceStat Range = new PerformanceStat();
[InspectablePrefab, JsonProperty("effect"), Key(4)]
public string EffectPrefab;
}
[InspectableField, JsonProperty("burstCount"), Key(4)]
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
public abstract class InstantWeaponData : WeaponData
{
[InspectableField, JsonProperty("burstCount"), Key(5)]
public int BurstCount;
[InspectableField, JsonProperty("burstTime"), Key(5)]
[InspectableField, JsonProperty("burstTime"), Key(6)]
public PerformanceStat BurstTime = new PerformanceStat();
}
public class InstantWeapon : IBehavior, IAlwaysUpdatedBehavior
{
private InstantWeaponData _data;
public int _burstCount;
public float _burstTimer;
private Entity Entity { get; }
private EquippedItem Item { get; }
private ItemManager Context { get; }
public BehaviorData Data => _data;
public event Action OnFire;
private float _burstTime;
public InstantWeapon(ItemManager context, InstantWeaponData c, Entity entity, EquippedItem item)
{
Context = context;
_data = c;
Entity = entity;
Item = item;
}
// private void Fire()
// {
// Hardpoint.Temperature += _projectileWeapon.Heat.Evaluate(Hardpoint) / Hardpoint.HeatCapacity;
// var inst = GameObject.Instantiate(_projectileWeapon.BulletPrefab).transform;
// Physics.IgnoreCollision(Hardpoint.Ship.Ship.GetComponent<Collider>(), inst.GetComponent<Collider>());
// var bullet = inst.GetComponent<Bullet>();
// bullet.Target = Hardpoint.Ship.Ship.Target;
// bullet.Source = Hardpoint.Ship.Ship.Hitpoints;
// bullet.Lifetime = _projectileWeapon.Range.Evaluate(Hardpoint) / _projectileWeapon.Velocity.Evaluate(Hardpoint);
// bullet.Damage = _projectileWeapon.Damage.Evaluate(Hardpoint);
// inst.position = Hardpoint.Proxy.position;
// inst.rotation = Hardpoint.Proxy.rotation;
// inst.GetComponent<Rigidbody>().velocity = _projectileWeapon.Velocity.Evaluate(Hardpoint) * Vector3.RotateTowards(-inst.forward, Hardpoint.Ship.Ship.Direction, _projectileWeapon.Deflection * Mathf.Deg2Rad, 1);
// Hardpoint.Ship.Ship.AudioSource.PlayOneShot(_projectileWeapon.Sounds.RandomElement());
// Debug.Log($"Firing bullet {b}");
// }
public bool Update(float delta)
{
_burstTime = Context.Evaluate(_data.BurstTime, Item.EquippableItem, Entity) / _burstCount;
if (_burstTime < .01f)
{
for(int i=0; i<_data.BurstCount; i++)
OnFire?.Invoke();
}
else
{
_burstCount = _data.BurstCount;
Fire();
}
return true;
}
private void Fire()
{
_burstCount--;
_burstTimer = _burstTime;
OnFire?.Invoke();
}
public void AlwaysUpdate(float delta)
{
if(_burstCount > 0)
{
_burstTimer -= delta;
if(_burstTimer < 0)
Fire();
}
}
}

View file

@ -38,6 +38,9 @@ public abstract class Entity
public Entity Parent;
public List<Entity> Children = new List<Entity>();
public Entity Target;
public float3 LookDirection;
public string Name;
@ -56,7 +59,7 @@ public abstract class Entity
public HardpointData[,] Hardpoints;
private EquippedItem[] _orderedEquipment;
private bool _active;
protected bool _active;
public ItemManager ItemManager { get; }
public int AssignedPopulation => PopulationAssignments.Sum(pa => pa.AssignedPopulation);
@ -77,10 +80,13 @@ public abstract class Entity
if(behavior is IInitializableBehavior initializableBehavior)
initializableBehavior.Initialize();
}
OnActivate();
}
}
}
protected virtual void OnActivate(){}
public Entity(ItemManager itemManager, Zone zone, EquippableItem hull)
{
ItemManager = itemManager;
@ -231,9 +237,10 @@ public abstract class Entity
foreach (var i in itemData.Shape.Coordinates)
{
// If there is any gear already occupying that space, it won't fit
// If there's a hardpoint there, it won't fit
// Thermal items have their own layer and do not collide with gear
var itemCoord = hullCoord + itemData.Shape.Rotate(i, item.Rotation);
if (!hullData.InteriorCells[itemCoord] || (itemData.HardpointType == HardpointType.Thermal ? ThermalOccupancy : GearOccupancy)[itemCoord.x, itemCoord.y] != null) return false;
if (!hullData.InteriorCells[itemCoord] || (itemData.HardpointType == HardpointType.Tool && Hardpoints[itemCoord.x, itemCoord.y] != null) || (itemData.HardpointType == HardpointType.Thermal ? ThermalOccupancy : GearOccupancy)[itemCoord.x, itemCoord.y] != null) return false;
}
}
else
@ -661,6 +668,9 @@ public class EquippedItem
// EquippableItem.Durability -= delta;
// return;
// }
foreach (var behavior in Behaviors.Where(b => b is IAlwaysUpdatedBehavior).Cast<IAlwaysUpdatedBehavior>())
behavior.AlwaysUpdate(delta);
foreach (var group in BehaviorGroups)
{
@ -670,9 +680,6 @@ public class EquippedItem
break;
}
}
foreach (var behavior in Behaviors.Where(b => b is IAlwaysUpdatedBehavior).Cast<IAlwaysUpdatedBehavior>())
behavior.AlwaysUpdate(delta);
}
}

View file

@ -22,7 +22,27 @@ public class Ship : Entity
// [IgnoreMember] public Dictionary<Targetable, float> Contacts = new Dictionary<Targetable, float>();
// [IgnoreMember] public Targetable Target;
public Entity HomeEntity;
public float2 MovementDirection;
private Thruster[] _allThrusters;
private Thruster[] _forwardThrusters;
private Thruster[] _reverseThrusters;
private Thruster[] _rightThrusters;
private Thruster[] _leftThrusters;
private Thruster[] _clockwiseThrusters;
private Thruster[] _counterClockwiseThrusters;
protected override void OnActivate()
{
_allThrusters = GetBehaviors<Thruster>().ToArray();
_forwardThrusters = _allThrusters.Where(x => x.Item.EquippableItem.Rotation == ItemRotation.Reversed).ToArray();
_reverseThrusters = _allThrusters.Where(x => x.Item.EquippableItem.Rotation == ItemRotation.None).ToArray();
_rightThrusters = _allThrusters.Where(x => x.Item.EquippableItem.Rotation == ItemRotation.CounterClockwise).ToArray();
_leftThrusters = _allThrusters.Where(x => x.Item.EquippableItem.Rotation == ItemRotation.Clockwise).ToArray();
_counterClockwiseThrusters = _allThrusters.Where(x => x.Torque < -.05f).ToArray();
_clockwiseThrusters = _allThrusters.Where(x => x.Torque > .05f).ToArray();
}
public Ship(ItemManager itemManager, Zone zone, EquippableItem hull) : base(itemManager, zone, hull)
{
}
@ -30,6 +50,21 @@ public class Ship : Entity
public override void Update(float delta)
{
Position += Velocity * delta;
if (_active)
{
foreach (var thruster in _allThrusters) thruster.Axis = 0;
foreach (var thruster in _rightThrusters) thruster.Axis += MovementDirection.x;
foreach (var thruster in _leftThrusters) thruster.Axis += -MovementDirection.x;
foreach (var thruster in _forwardThrusters) thruster.Axis += MovementDirection.y;
foreach (var thruster in _reverseThrusters) thruster.Axis += -MovementDirection.y;
var deltaRot = dot(normalize(LookDirection.xz), normalize(Direction).Rotate(ItemRotation.Clockwise));
if (abs(deltaRot) < .01) deltaRot = 0;
deltaRot = pow(abs(deltaRot), .5f) * sign(deltaRot);
foreach (var thruster in _clockwiseThrusters) thruster.Axis += deltaRot;
foreach (var thruster in _counterClockwiseThrusters) thruster.Axis += -deltaRot;
}
base.Update(delta);
}
}