init
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 897421123bd34936921a8901d8256c7a
|
||||
timeCreated: 1666646438
|
||||
@@ -0,0 +1,298 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.Utilities;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Dict.Ability;
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Projectile;
|
||||
using VOID.Generic.Util;
|
||||
using VOID.ScriptableObjects;
|
||||
using VOID.ScriptableObjects.Abilities;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// Makes <see cref="UnitObject"/> cast given <see cref="BasicAbility"/>.
|
||||
/// <br/><br/>
|
||||
/// <see cref="AbstractAction"/>:<br/>
|
||||
/// <inheritdoc cref="AbstractAction"/>
|
||||
/// </summary>
|
||||
public class AbilityAction : AbstractAction
|
||||
{
|
||||
private class Target
|
||||
{
|
||||
public readonly AbstractObject targetObject;
|
||||
public readonly Vector3 targetPosition;
|
||||
|
||||
public Target(AbstractObject targetObject, Vector3 targetPosition)
|
||||
{
|
||||
this.targetObject = targetObject;
|
||||
this.targetPosition = targetPosition;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly UnitObject _unit;
|
||||
private readonly BasicAbility _ability;
|
||||
private readonly Target[] _targets;
|
||||
|
||||
private int _projectilesEnded;
|
||||
private AbilityCastEvent _abilityEvent;
|
||||
|
||||
public AbilityAction(UnitObject unit, BasicAbility ability)
|
||||
: this(unit, ability, Array.Empty<Target>())
|
||||
{
|
||||
}
|
||||
|
||||
public AbilityAction(UnitObject unit, BasicAbility ability, Vector3 target)
|
||||
: this(unit, ability, new[] { new Target(null, target) })
|
||||
{
|
||||
}
|
||||
|
||||
public AbilityAction(UnitObject unit, BasicAbility ability, AbstractObject target)
|
||||
: this(unit, ability, new[] { new Target(target, target.transform.position + Vector3.up * target.basicData.height/2) })
|
||||
{
|
||||
}
|
||||
|
||||
private AbilityAction(UnitObject unit, BasicAbility ability, Target target)
|
||||
: this(unit, ability, new[] { target })
|
||||
{
|
||||
}
|
||||
|
||||
public AbilityAction(UnitObject unit, BasicAbility ability, IEnumerable<Vector3> targets)
|
||||
: this(unit, ability, targets.Select(p => new Target(null, p)).ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
public AbilityAction(UnitObject unit, BasicAbility ability, IEnumerable<AbstractObject> targets)
|
||||
: this(unit, ability, targets.Select(o => new Target(o, o.transform.position+ Vector3.up * o.basicData.height/2)).ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
private AbilityAction(UnitObject unit, BasicAbility ability, Target[] targets)
|
||||
{
|
||||
_unit = unit;
|
||||
_ability = ability;
|
||||
_targets = targets;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
return _targets.IsNullOrEmpty() || _targets.All(target =>
|
||||
target.targetObject
|
||||
? RangeUtil.IsInRange(_unit, target.targetObject, _ability.range)
|
||||
: RangeUtil.IsInRange(_unit, target.targetPosition, _ability.range));
|
||||
}
|
||||
|
||||
public override bool CanBeStopped() => _abilityEvent is null || _abilityEvent.prevented;
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.unitData.currentResources.actionPoints >= _ability.actionPointCost,
|
||||
UnitActionErrorType.UnitNotEnoughActionPoints);
|
||||
Check(
|
||||
_unit.unitData.currentResources.movePoints >= _ability.movePointCost,
|
||||
UnitActionErrorType.UnitNotEnoughMovePoints);
|
||||
}
|
||||
|
||||
Check(
|
||||
_ability is not BasicAttackAbility || _unit.unitData.canAttack,
|
||||
UnitActionErrorType.ThisUnitCantAttack);
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
Check(
|
||||
_ability.requirements.All(requirement => requirement.Check(_unit)),
|
||||
UnitActionErrorType.RequirementsNotMeetToUseThatAbility);
|
||||
Check(
|
||||
_ability.projectileSteps.First().validTargets.All(validTarget =>
|
||||
_targets.All(target => validTarget.IsValid(_unit, target.targetPosition, target.targetObject))),
|
||||
UnitActionErrorType.WrongTargetsSelectedToUseThatAbility);
|
||||
Check(
|
||||
_ability.aimingType is AbilityAimingType.Blank || _ability.castUsages == _targets.Length,
|
||||
UnitActionErrorType.WrongNumberOfTargetsToUseThatAbility);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
_unit.unitData.UseResource(UnitResourceType.ActionPoints, _ability.actionPointCost);
|
||||
_unit.unitData.UseResource(UnitResourceType.MovePoints, _ability.movePointCost);
|
||||
}
|
||||
|
||||
_abilityEvent = new AbilityCastEvent
|
||||
{
|
||||
caster = _unit,
|
||||
ability = _ability
|
||||
};
|
||||
|
||||
_unit.unitEvents.onStartAbilityBefore.Invoke(_abilityEvent);
|
||||
|
||||
Check(!_abilityEvent.prevented, UnitActionErrorType.AbilityIsPrevented);
|
||||
|
||||
_unit.unitEvents.onStartAbilityAfter.Invoke(_abilityEvent);
|
||||
|
||||
if (_ability.castingType == AbilityCastingType.Instant)
|
||||
{
|
||||
DoAbility(null);
|
||||
EndIt();
|
||||
return;
|
||||
}
|
||||
|
||||
var animationGenericEvent = new AnimationGenericEvent
|
||||
{
|
||||
animationType = AnimationType.Ability,
|
||||
unit = _unit,
|
||||
ability = _ability
|
||||
};
|
||||
|
||||
if (_targets.Length > 0) new RotateAction(_unit, _targets[0].targetPosition).DoIt();
|
||||
|
||||
if (_ability.castingType is AbilityCastingType.Channel && _ability.castUsages > 0)
|
||||
{
|
||||
// When channeling - ability ends when all projectiles end
|
||||
_unit.unitEvents.onAnimation[AnimationType.Ability].onPerform.AddListener(DoAbility);
|
||||
_unit.unitAnimator.SetLoopAnimation(AnimationType.Ability, _ability.abilityLoopAnimationList);
|
||||
_unit.unitAnimator.StartLoopAnimation(animationGenericEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise - ability ends with animation
|
||||
_unit.unitEvents.onAnimation[AnimationType.Ability].onPerform.AddListener(DoAbility);
|
||||
_unit.unitEvents.onAnimation[AnimationType.Ability].onEnd.AddListener(OnAbilityEnd);
|
||||
_unit.unitAnimator.SetAnimation(AnimationType.Ability, _ability.abilityAnimationList);
|
||||
_unit.unitAnimator.StartAnimation(animationGenericEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoAbility(AnimationGenericEvent tEvent)
|
||||
{
|
||||
BeforePerform();
|
||||
if (_ability.applyOnCasterMoment is AbilityExecutionMoment.AfterCast) ApplyEffectsToCaster();
|
||||
_targets.ForEach((target, index) =>
|
||||
{
|
||||
// Predefined object is only for visual things
|
||||
// Else - new empty projectile object
|
||||
var projectile = _ability.projectile
|
||||
? Object.Instantiate(_ability.projectile.gameObject).GetComponent<ProjectileObject>()
|
||||
: new GameObject().AddComponent<ProjectileObject>();
|
||||
|
||||
projectile.StartProjectile(index, _unit, _unit.unitData.castPosition.position, target.targetPosition, _ability.projectileSteps);
|
||||
projectile.onHit.AddListener(OnProjectileHit);
|
||||
projectile.onEnd.AddListener(OnProjectileEnd);
|
||||
|
||||
_unit.unitEvents.onAbilityProjectileStart.Invoke(new AbilityProjectileEvent
|
||||
{
|
||||
caster = _unit,
|
||||
ability = _ability,
|
||||
projectileIndex = index,
|
||||
projectile = projectile
|
||||
});
|
||||
});
|
||||
AfterPerform();
|
||||
}
|
||||
|
||||
private void OnProjectileHit(ProjectileObject projectile, AbstractObject hitObject)
|
||||
{
|
||||
var abilityHitEvent = new AbilityHitEvent
|
||||
{
|
||||
caster = _unit,
|
||||
target = hitObject,
|
||||
ability = _ability
|
||||
};
|
||||
|
||||
hitObject.basicEvents.onAbilityHitBefore.Invoke(abilityHitEvent);
|
||||
_unit.unitEvents.onAbilityHitBefore.Invoke(abilityHitEvent);
|
||||
|
||||
// We cant run Check here, because this OnHit can be one of many - just do nothing more for this projectile
|
||||
if (abilityHitEvent.prevented) return;
|
||||
|
||||
hitObject.basicEvents.onAbilityHitAfter.Invoke(abilityHitEvent);
|
||||
_unit.unitEvents.onAbilityHitAfter.Invoke(abilityHitEvent);
|
||||
|
||||
ApplyEffectsToTarget(hitObject);
|
||||
}
|
||||
|
||||
private void OnProjectileEnd(ProjectileObject projectile)
|
||||
{
|
||||
_projectilesEnded++;
|
||||
|
||||
_unit.unitEvents.onAbilityProjectileEnd.Invoke(new AbilityProjectileEvent
|
||||
{
|
||||
caster = _unit,
|
||||
ability = _ability,
|
||||
projectileIndex = projectile.index,
|
||||
projectile = projectile
|
||||
});
|
||||
|
||||
if (_ability.castingType is AbilityCastingType.Channel && _projectilesEnded == _ability.castUsages)
|
||||
{
|
||||
_unit.unitAnimator.EndLoopAnimation();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyEffectsToTarget(AbstractObject target)
|
||||
{
|
||||
if (_ability.applyOnTarget.Count <= 0) return;
|
||||
|
||||
// Because ability have defined only effects we need create dummy status
|
||||
// IMPORTANT - It is hidden and instantly starts and then ends!
|
||||
var targetStatus = ScriptableObject.CreateInstance<BasicStatus>();
|
||||
targetStatus.effects = _ability.applyOnTarget;
|
||||
targetStatus.hidden = true;
|
||||
target.statusManager.AddStatus(targetStatus, _unit, false);
|
||||
}
|
||||
|
||||
private void ApplyEffectsToCaster()
|
||||
{
|
||||
if (_ability.applyOnCaster.Count <= 0) return;
|
||||
|
||||
// Because ability have defined only effects we need create dummy status
|
||||
// IMPORTANT - It is hidden and instantly starts and then ends!
|
||||
var casterStatus = ScriptableObject.CreateInstance<BasicStatus>();
|
||||
casterStatus.effects = _ability.applyOnCaster;
|
||||
casterStatus.hidden = true;
|
||||
_unit.statusManager.AddStatus(casterStatus, _unit, false);
|
||||
}
|
||||
|
||||
private void OnAbilityEnd(AnimationGenericEvent tEvent)
|
||||
{
|
||||
EndIt();
|
||||
}
|
||||
|
||||
protected override void OnCancelIt()
|
||||
{
|
||||
_unit.unitAnimator.EndLoopAnimation();
|
||||
_unit.unitEvents.onAnimation[AnimationType.Ability].onPerform.RemoveListener(DoAbility);
|
||||
_unit.unitEvents.onAnimation[AnimationType.Ability].onEnd.RemoveListener(OnAbilityEnd);
|
||||
_unit.unitEvents.onEndAbility.Invoke(_abilityEvent);
|
||||
}
|
||||
|
||||
protected override void OnEndIt()
|
||||
{
|
||||
_unit.unitAnimator.EndLoopAnimation();
|
||||
if (_ability.applyOnCasterMoment is AbilityExecutionMoment.AfterEnd) ApplyEffectsToCaster();
|
||||
_unit.unitEvents.onAnimation[AnimationType.Ability].onPerform.RemoveListener(DoAbility);
|
||||
_unit.unitEvents.onAnimation[AnimationType.Ability].onEnd.RemoveListener(OnAbilityEnd);
|
||||
_unit.unitEvents.onEndAbility.Invoke(_abilityEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f347d6a2844a436db125cd102e83d5de
|
||||
timeCreated: 1677173609
|
||||
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using Sirenix.Utilities;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public enum ActionState
|
||||
{
|
||||
Ready,
|
||||
Running,
|
||||
Finished,
|
||||
Cancelled
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action for <see cref="UnitObject"/>.<br/>
|
||||
///
|
||||
/// Executing order when <see cref="DoIt"/> used:<br/>
|
||||
/// <ul>
|
||||
/// <li><see cref="CanDoIt"/></li>
|
||||
/// <li><see cref="OnDo"/></li>
|
||||
/// <li><see cref="OnDoIt"/></li>
|
||||
/// <li>Inside OnDoIt: <see cref="OnBeforePerform"/></li>
|
||||
/// <li>Inside OnDoIt: Action's logic here</li>
|
||||
/// <li>Inside OnDoIt: <see cref="OnAfterPerform"/> - obligatory if action ends immediately</li>
|
||||
/// </ul>
|
||||
///
|
||||
/// Executing order when <see cref="EndIt"/> used:<br/>
|
||||
/// <ul>
|
||||
/// <li><see cref="OnEndIt"/></li>
|
||||
/// <li>Inside OnEndIt: <see cref="OnAfterPerform"/> - obligatory if not used in OnDoIt</li>
|
||||
/// <li><see cref="OnEnd"/></li>
|
||||
/// </ul>
|
||||
///
|
||||
/// Executing order when <see cref="CancelIt"/> used:<br/>
|
||||
/// <ul>
|
||||
/// <li><see cref="OnCancelIt"/></li>
|
||||
/// <li>Inside OnCancelIt: <see cref="OnAfterPerform"/> - obligatory if not used in OnDoIt</li>
|
||||
/// <li><see cref="OnCancel"/></li>
|
||||
/// </ul>
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public abstract class AbstractAction
|
||||
{
|
||||
/// <summary>Run after checking and before executing action.</summary>
|
||||
public event Action OnDo;
|
||||
|
||||
/// <summary>Defined by referenced action. Usually right *before* main point of that action.</summary>
|
||||
public event Action OnBeforePerform;
|
||||
|
||||
/// <summary>Defined by referenced action. Usually right *after* main point of that action.</summary>
|
||||
public event Action OnAfterPerform;
|
||||
|
||||
/// <summary>Run after action ended.</summary>
|
||||
public event Action OnEnd;
|
||||
|
||||
/// <summary>Run after action ended forcefully.</summary>
|
||||
public event Action OnCancel;
|
||||
|
||||
/// <summary>Current state of action.</summary>
|
||||
public ActionState state { get; protected set; } = ActionState.Ready;
|
||||
|
||||
/// <summary>If given, current action will be executed only if given one is finished successfully</summary>
|
||||
public AbstractAction runAfterAction;
|
||||
|
||||
/// <summary>Simple check if unit is in range to execute this action.</summary>
|
||||
public abstract bool IsInRange();
|
||||
|
||||
/// <summary>Determines whether this action CAN be executed INSTANTLY outside the queue.</summary>
|
||||
public virtual bool CanSkipQueue() => false;
|
||||
|
||||
/// <summary>Determines whether this action CAN be stopped early, by something else besides itself.</summary>
|
||||
public virtual bool CanBeStopped() => true;
|
||||
|
||||
/// <summary>Action's checks if action can be executed. <see cref="Check"/> have to be used here.</summary>
|
||||
public abstract void CanDoIt();
|
||||
|
||||
/// <summary>Action's logic.</summary>
|
||||
protected abstract void OnDoIt();
|
||||
|
||||
/// <summary>Action's logic when whole action ends successfully.</summary>
|
||||
protected abstract void OnEndIt();
|
||||
|
||||
/// <summary>Action's logic when whole action is forced to end.</summary>
|
||||
protected abstract void OnCancelIt();
|
||||
|
||||
public bool CanDoItBoolean()
|
||||
{
|
||||
try
|
||||
{
|
||||
CanDoIt();
|
||||
return true;
|
||||
}
|
||||
catch (UnitActionErrorException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 1. Checking if action can be done by function in child: <see cref="CanDoIt"/><br/>
|
||||
/// 2. Executing main login of this action
|
||||
/// </summary>
|
||||
public void DoIt()
|
||||
{
|
||||
Check(
|
||||
runAfterAction == null || runAfterAction.state == ActionState.Finished,
|
||||
UnitActionErrorType.PreviousActionNotFinished);
|
||||
CanDoIt();
|
||||
state = ActionState.Running;
|
||||
OnDo?.Invoke();
|
||||
OnDoIt();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executed by action itself when everything is done correctly.
|
||||
/// </summary>
|
||||
protected void EndIt()
|
||||
{
|
||||
if (state is ActionState.Finished or ActionState.Cancelled)
|
||||
{
|
||||
Debug.LogWarning($"{GetType().GetNiceName()} can't be ended. State: '{state}'");
|
||||
return;
|
||||
}
|
||||
|
||||
OnEndIt();
|
||||
state = ActionState.Finished;
|
||||
OnEnd?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executed by external source. Stopping this action forcefully.
|
||||
/// </summary>
|
||||
public void CancelIt()
|
||||
{
|
||||
// Cancel events only when action really started otherwise there will be nothing to cancel
|
||||
if (state == ActionState.Running)
|
||||
{
|
||||
OnCancelIt();
|
||||
OnCancel?.Invoke();
|
||||
}
|
||||
|
||||
state = ActionState.Cancelled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be executed from child right before main logic is started, usually in <see cref="OnDoIt"/>
|
||||
/// </summary>
|
||||
protected void BeforePerform()
|
||||
{
|
||||
OnBeforePerform?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be executed from child right after main logic is done, usually in <see cref="OnDoIt"/>
|
||||
/// </summary>
|
||||
protected void AfterPerform()
|
||||
{
|
||||
OnAfterPerform?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute <see cref="Throw"/> if check is false
|
||||
/// </summary>
|
||||
protected void Check(bool condition, UnitActionErrorType elseError)
|
||||
{
|
||||
if (!condition) Throw(elseError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels this Action and then throw <see cref="UnitActionErrorException"/>
|
||||
/// </summary>
|
||||
protected void Throw(UnitActionErrorType errorType)
|
||||
{
|
||||
CancelIt();
|
||||
throw new UnitActionErrorException(this, errorType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d54967e8cbfc4281ba14d76077012bf1
|
||||
timeCreated: 1666646484
|
||||
@@ -0,0 +1,104 @@
|
||||
using System.Linq;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Dict.Ability;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.ScriptableObjects.Abilities;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// Simply make <see cref="UnitObject"/> go into "casting" state allowing player or AI to aim and select targets.
|
||||
/// <br/><br/>
|
||||
/// <see cref="AbstractAction"/>:<br/>
|
||||
/// <inheritdoc cref="AbstractAction"/>
|
||||
/// </summary>
|
||||
public class CastingAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly BasicAbility _ability;
|
||||
|
||||
public CastingAction(UnitObject unit, BasicAbility ability)
|
||||
{
|
||||
_unit = unit;
|
||||
_ability = ability;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.unitData.currentResources.actionPoints >= _ability.actionPointCost,
|
||||
UnitActionErrorType.UnitNotEnoughActionPoints);
|
||||
Check(
|
||||
_unit.unitData.currentResources.movePoints >= _ability.movePointCost,
|
||||
UnitActionErrorType.UnitNotEnoughMovePoints);
|
||||
}
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
_ability.requirements.All(requirement => requirement.Check(_unit)),
|
||||
UnitActionErrorType.RequirementsNotMeetToUseThatAbility);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
BeforePerform();
|
||||
|
||||
if (_ability.castingType is AbilityCastingType.Instant or AbilityCastingType.InstantCasting)
|
||||
{
|
||||
// Ending action early
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
|
||||
// Make sure that there is no more actions after CASTING and before ABILITY
|
||||
_unit.OrderStop(false);
|
||||
|
||||
// Instantly starting ability
|
||||
_unit.Order(new AbilityAction(_unit, _ability));
|
||||
return;
|
||||
}
|
||||
|
||||
var animationGenericEvent = new AnimationGenericEvent
|
||||
{
|
||||
animationType = AnimationType.Casting,
|
||||
unit = _unit,
|
||||
ability = _ability
|
||||
};
|
||||
|
||||
// Enables "casting" mode for this unit (usually only for player) to select targets before firing ability
|
||||
_unit.unitEvents.onStartCasting.Invoke(new CastingEvent { caster = _unit, ability = _ability });
|
||||
|
||||
// Starting loop animation of selected ability
|
||||
_unit.unitAnimator.SetLoopAnimation(AnimationType.Casting, _ability.castingAnimationList);
|
||||
_unit.unitAnimator.StartLoopAnimation(animationGenericEvent);
|
||||
}
|
||||
|
||||
protected override void OnEndIt()
|
||||
{
|
||||
AfterPerform();
|
||||
|
||||
// Instant abilities don't have casting - do nothing
|
||||
if (_ability.castingType is AbilityCastingType.Instant or AbilityCastingType.InstantCasting) return;
|
||||
|
||||
// Somehow casting ended (no matter is by player or something else)
|
||||
_unit.unitAnimator.EndLoopAnimation();
|
||||
_unit.unitEvents.onEndCasting.Invoke(new CastingEvent { caster = _unit, ability = _ability });
|
||||
}
|
||||
|
||||
protected override void OnCancelIt()
|
||||
{
|
||||
OnEndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d459cfb11f942dd853b4314f8f70c1c
|
||||
timeCreated: 1689964527
|
||||
@@ -0,0 +1,47 @@
|
||||
using VOID.Generic.Objects.Container;
|
||||
using VOID.Generic.Objects.Container.Events;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class CloseContainerAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly ContainerObject _container;
|
||||
|
||||
public CloseContainerAction(UnitObject unit, ContainerObject container)
|
||||
{
|
||||
_unit = unit;
|
||||
_container = container;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
public override bool CanSkipQueue() => true;
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
_container.containerState.openedBy.Contains(_unit),
|
||||
UnitActionErrorType.ContainerIsNotOpenedByThisUnit);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
var containerCloseEvent = new ContainerCloseEvent
|
||||
{
|
||||
closedBy = _unit,
|
||||
container = _container
|
||||
};
|
||||
|
||||
BeforePerform();
|
||||
_container.containerEvents.onClose.Invoke(containerCloseEvent);
|
||||
_unit.unitEvents.onContainerClose.Invoke(containerCloseEvent);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f799f6c37f44f70b1c8b3408771bbb6
|
||||
timeCreated: 1694902221
|
||||
@@ -0,0 +1,45 @@
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class CloseOtherUnitAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly UnitObject _otherUnit;
|
||||
|
||||
public CloseOtherUnitAction(UnitObject unit, UnitObject otherUnit)
|
||||
{
|
||||
_unit = unit;
|
||||
_otherUnit = otherUnit;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
_otherUnit.unitState.openedBy.Contains(_unit),
|
||||
UnitActionErrorType.OtherUnitIsNotOpenedByThisUnit);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
var closeOtherUnitEvent = new CloseOtherUnitEvent()
|
||||
{
|
||||
closedBy = _unit,
|
||||
otherUnit = _otherUnit
|
||||
};
|
||||
|
||||
BeforePerform();
|
||||
_otherUnit.unitEvents.onClosedByOtherUnit.Invoke(closeOtherUnitEvent);
|
||||
_unit.unitEvents.onCloseOtherUnit.Invoke(closeOtherUnitEvent);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3fd8d298c2c47288cada9a8d6dc7a51
|
||||
timeCreated: 1717948914
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class CustomAction : AbstractAction
|
||||
{
|
||||
private event Action<UnitObject> Action;
|
||||
private readonly UnitObject _unit;
|
||||
|
||||
public CustomAction(UnitObject unit, Action<UnitObject> actionToDo)
|
||||
{
|
||||
_unit = unit;
|
||||
Action += actionToDo;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
public override bool CanSkipQueue() => true;
|
||||
|
||||
protected override void OnCancelIt() {}
|
||||
protected override void OnEndIt() {}
|
||||
public override void CanDoIt() {}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
BeforePerform();
|
||||
Action?.Invoke(_unit);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09492cbb5b6646b0acc1ea577c114534
|
||||
timeCreated: 1690487463
|
||||
@@ -0,0 +1,116 @@
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Item;
|
||||
using VOID.Generic.Objects.Item.Events;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Wearable;
|
||||
using VOID.Generic.Objects.Wearable.Events;
|
||||
using VOID.Generic.Util;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class DropAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly ItemObject _item;
|
||||
private readonly Vector3 _dropPosition;
|
||||
|
||||
public DropAction(UnitObject unit, ItemObject item)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
_dropPosition = unit.transform.position;
|
||||
}
|
||||
|
||||
public DropAction(UnitObject unit, ItemObject item, Vector3 dropPosition)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
_dropPosition = dropPosition;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
return RangeUtil.IsInRange(_unit, _item, _unit.unitData.takeRange);
|
||||
}
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.unitData.currentResources.actionPoints >= 1,
|
||||
UnitActionErrorType.UnitNotEnoughActionPoints);
|
||||
}
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
_item.itemState.carriedBy == _unit,
|
||||
UnitActionErrorType.UnitDontCarryThatItem);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
if (_unit.basicState.turnManager)
|
||||
_unit.unitData.UseResource(UnitResourceType.ActionPoints, 1);
|
||||
|
||||
TryToUnEquip();
|
||||
|
||||
var dropEvent = new DropEvent
|
||||
{
|
||||
item = _item,
|
||||
unit = _unit
|
||||
};
|
||||
|
||||
_item.itemEvents.onDroppedBefore.Invoke(dropEvent);
|
||||
_unit.unitEvents.onDropBefore.Invoke(dropEvent);
|
||||
|
||||
Check(!dropEvent.prevented, UnitActionErrorType.DropIsPrevented);
|
||||
|
||||
_unit.OrderInstantly(new RotateAction(_unit, _dropPosition));
|
||||
BeforePerform();
|
||||
_unit.unitBackpack.Drop(_item);
|
||||
_item.transform.position = _dropPosition;
|
||||
_item.itemEvents.onDroppedAfter.Invoke(dropEvent);
|
||||
_unit.unitEvents.onDropAfter.Invoke(dropEvent);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
|
||||
private void TryToUnEquip()
|
||||
{
|
||||
if (_item is not WearableObject item) return;
|
||||
if (!item.wearableState.wearerUnit) return;
|
||||
|
||||
var unEquipEvent = new UnEquipEvent
|
||||
{
|
||||
wearable = item,
|
||||
unit = _unit
|
||||
};
|
||||
|
||||
item.wearableEvents.onUnEquippedBefore.Invoke(unEquipEvent);
|
||||
_unit.unitEvents.onUnEquipBefore.Invoke(unEquipEvent);
|
||||
|
||||
Check(!unEquipEvent.prevented, UnitActionErrorType.UnEquipIsPrevented);
|
||||
|
||||
_unit.unitEquipment.UnEquip(item);
|
||||
_unit.unitBackpack.Take(item);
|
||||
|
||||
item.wearableEvents.onUnEquippedAfter.Invoke(unEquipEvent);
|
||||
_unit.unitEvents.onUnEquipAfter.Invoke(unEquipEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3039a96dd3034f6da5cc4d935e85fc8f
|
||||
timeCreated: 1672679513
|
||||
@@ -0,0 +1,40 @@
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class EndTurnAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
|
||||
public EndTurnAction(UnitObject unit)
|
||||
{
|
||||
_unit = unit;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
public override bool CanSkipQueue() => true;
|
||||
|
||||
protected override void OnEndIt() { }
|
||||
|
||||
protected override void OnCancelIt() { }
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
Check(
|
||||
_unit.basicState.turnManager,
|
||||
UnitActionErrorType.UnitNotInTurnManager);
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
_unit.unitActionQueue.StopQueue();
|
||||
_unit.basicState.turnManager.NextTurn();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc0b140f8b9e48c9ab03ee75abd389fb
|
||||
timeCreated: 1696970563
|
||||
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Accessory;
|
||||
using VOID.Generic.Objects.Armor;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Weapon;
|
||||
using VOID.Generic.Objects.Wearable;
|
||||
using VOID.Generic.Objects.Wearable.Events;
|
||||
using static VOID.Generic.Util.WearableUtils;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class EquipAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly WearableObject _item;
|
||||
private readonly int _slotIndex;
|
||||
private readonly EquipmentSlotType _slot;
|
||||
|
||||
public EquipAction(UnitObject unit, WearableObject item, int slotIndex)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
_slotIndex = slotIndex;
|
||||
_slot = (EquipmentSlotType)slotIndex;
|
||||
}
|
||||
|
||||
public EquipAction(UnitObject unit, WearableObject item)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
_slot = FindEquipmentSlot();
|
||||
_slotIndex = (int)_slot;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.unitData.currentResources.actionPoints >= 1,
|
||||
UnitActionErrorType.UnitNotEnoughActionPoints);
|
||||
}
|
||||
Check(
|
||||
_unit.unitEquipment.CanEquipInSlot(_slotIndex, _item),
|
||||
UnitActionErrorType.CannotEquipItemInThatSlot);
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
_item.itemState.carriedBy == _unit,
|
||||
UnitActionErrorType.UnitDontCarryThatItem);
|
||||
Check(
|
||||
_item.wearableData.requirements.All(requirement => requirement.Check(_unit)),
|
||||
UnitActionErrorType.RequirementsNotMeetToEquipThatItem);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
if (_unit.basicState.turnManager)
|
||||
_unit.unitData.UseResource(UnitResourceType.ActionPoints, 1);
|
||||
|
||||
var equipEvent = new EquipEvent
|
||||
{
|
||||
wearable = _item,
|
||||
unit = _unit,
|
||||
slotIndex = _slotIndex,
|
||||
slotType = _slot
|
||||
};
|
||||
|
||||
_item.wearableEvents.onEquippedBefore.Invoke(equipEvent);
|
||||
_unit.unitEvents.onEquipBefore.Invoke(equipEvent);
|
||||
|
||||
Check(!equipEvent.prevented, UnitActionErrorType.EquipIsPrevented);
|
||||
|
||||
TryToUnEquip();
|
||||
|
||||
BeforePerform();
|
||||
|
||||
// Move item from Backpack to Equipment
|
||||
_unit.unitBackpack.Drop(_item);
|
||||
_unit.unitEquipment.Equip(_slotIndex, _item);
|
||||
|
||||
// Execute events
|
||||
_item.wearableEvents.onEquippedAfter.Invoke(equipEvent);
|
||||
_unit.unitEvents.onEquipAfter.Invoke(equipEvent);
|
||||
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
|
||||
private void TryToUnEquip()
|
||||
{
|
||||
var toUnEquip = _unit.unitEquipment.GetEquipped(_slotIndex);
|
||||
if (toUnEquip) new UnEquipAction(_unit, toUnEquip).DoIt();
|
||||
|
||||
// All WearableObjects un-equip only this item where it will be equipped
|
||||
// EXCEPT WeaponObject - these also can un-equip additionally mainHand or offHand, only when dealing with two-handed weapons
|
||||
if (_item is not WeaponObject weapon) return;
|
||||
|
||||
var mainHand = _unit.unitEquipment.GetEquipped(EquipmentSlotType.MainHand) as WeaponObject;
|
||||
var offHand = _unit.unitEquipment.GetEquipped(EquipmentSlotType.OffHand) as WeaponObject;
|
||||
|
||||
// UNEQUIP MAINHAND - if it is two-hand, we try to equip something in offhand
|
||||
if (mainHand && _slot == EquipmentSlotType.OffHand && mainHand.weaponData.weaponCarryType is WeaponCarryType.TwoHand)
|
||||
new UnEquipAction(_unit, mainHand).DoIt();
|
||||
|
||||
// UNEQUIP OFFHAND - if we try to equip something two-handed
|
||||
if (offHand && weapon.weaponData.weaponCarryType == WeaponCarryType.TwoHand)
|
||||
new UnEquipAction(_unit, offHand).DoIt();
|
||||
}
|
||||
|
||||
private EquipmentSlotType FindEquipmentSlot()
|
||||
{
|
||||
var equippedRingOne = _unit.unitEquipment.GetEquipped(EquipmentSlotType.RingOne);
|
||||
var equippedRingTwo = _unit.unitEquipment.GetEquipped(EquipmentSlotType.RingTwo);
|
||||
return _item switch
|
||||
{
|
||||
WeaponObject when !IsWeaponCarryType(_item, WeaponCarryType.OneHandOff) => EquipmentSlotType.MainHand,
|
||||
WeaponObject when IsWeaponCarryType(_item, WeaponCarryType.OneHandOff) => EquipmentSlotType.OffHand,
|
||||
ArmorObject when IsType(_item, ArmorType.Helmet) => EquipmentSlotType.Helmet,
|
||||
ArmorObject when IsType(_item, ArmorType.Armor) => EquipmentSlotType.Armor,
|
||||
ArmorObject when IsType(_item, ArmorType.Pants) => EquipmentSlotType.Pants,
|
||||
ArmorObject when IsType(_item, ArmorType.Belt) => EquipmentSlotType.Belt,
|
||||
ArmorObject when IsType(_item, ArmorType.Boots) => EquipmentSlotType.Boots,
|
||||
ArmorObject when IsType(_item, ArmorType.Gloves) => EquipmentSlotType.Gloves,
|
||||
AccessoryObject when IsType(_item, AccessoryType.Necklace) => EquipmentSlotType.Necklace,
|
||||
AccessoryObject when IsType(_item, AccessoryType.Ring) && (!equippedRingOne || equippedRingTwo) => EquipmentSlotType.RingOne,
|
||||
AccessoryObject when IsType(_item, AccessoryType.Ring) && (equippedRingOne && !equippedRingTwo) => EquipmentSlotType.RingTwo,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(_item))
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12b6ec7b73134717a699ebfee51de603
|
||||
timeCreated: 1672746279
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fad3becb68f44f608f5c61b1fcf6fe1d
|
||||
timeCreated: 1686666458
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions.Exceptions
|
||||
{
|
||||
public class UnitActionErrorException : Exception
|
||||
{
|
||||
public readonly AbstractAction action;
|
||||
public readonly UnitActionErrorType unitActionErrorType;
|
||||
|
||||
public UnitActionErrorException(AbstractAction action, UnitActionErrorType unitActionErrorType)
|
||||
{
|
||||
this.action = action;
|
||||
this.unitActionErrorType = unitActionErrorType;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 875cbf9757a34df9a5e9679dfa3247e6
|
||||
timeCreated: 1686666485
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions.Exceptions
|
||||
{
|
||||
public static class UnitActionErrorMessage
|
||||
{
|
||||
private static readonly Dictionary<UnitActionErrorType, string> Messages = new()
|
||||
{
|
||||
[UnitActionErrorType.ActionStateIsNotReady] = "Can't do this action yet",
|
||||
[UnitActionErrorType.NotInRange] = "Target is out of range",
|
||||
[UnitActionErrorType.UnitStateIsNotControllable] = "Unit is busy",
|
||||
[UnitActionErrorType.UnitDontCarryThatItem] = "Unit don't carry that item",
|
||||
[UnitActionErrorType.UnitDontWearThatItem] = "Unit don't wear that item",
|
||||
[UnitActionErrorType.ItemIsNotOnGround] = "Item is not on ground",
|
||||
[UnitActionErrorType.RequirementsNotMeetToEquipThatItem] = "Unit don't meet requirement to equip that item",
|
||||
[UnitActionErrorType.CannotEquipItemInThatSlot] = "That item can't be equipped in this equipment slot",
|
||||
[UnitActionErrorType.RequirementsNotMeetToUseThatItem] = "Unit don't meet requirement to use that item",
|
||||
[UnitActionErrorType.RequirementsNotMeetToUseThatAbility] = "Unit don't meet requirement to use that ability",
|
||||
[UnitActionErrorType.UnEquipIsPrevented] = "UnEquip prevented",
|
||||
[UnitActionErrorType.DropIsPrevented] = "Drop prevented",
|
||||
[UnitActionErrorType.EquipIsPrevented] = "Equip prevented",
|
||||
[UnitActionErrorType.PickIsPrevented] = "Pick prevented",
|
||||
[UnitActionErrorType.UseIsPrevented] = "Use prevented",
|
||||
[UnitActionErrorType.ContainerIsNotOpenedByThisUnit] = "Container is not opened by this unit",
|
||||
[UnitActionErrorType.ItemIsNotMovable] = "That item can't be moved",
|
||||
[UnitActionErrorType.ItemIsNotPickable] = "That item can't be picked",
|
||||
[UnitActionErrorType.AbilityIsPrevented] = "Ability prevented",
|
||||
[UnitActionErrorType.AbilityHitIsPrevented] = "Ability hit prevented",
|
||||
[UnitActionErrorType.UsableNotEnoughStacks] = "Item don't have enough stacks to be used",
|
||||
[UnitActionErrorType.PreviousActionNotFinished] = "Previous required action wasn't finished",
|
||||
[UnitActionErrorType.UnitNotInTurnManager] = "Unit don't participate in any turn mechanics",
|
||||
[UnitActionErrorType.UnitSelfTurnNotActive] = "It's not this unit's turn",
|
||||
[UnitActionErrorType.UnitNotEnoughActionPoints] = "Not enough action points to do that",
|
||||
[UnitActionErrorType.UnitNotEnoughMovePoints] = "Not enough move points to do that",
|
||||
[UnitActionErrorType.TalkNotAvailableWhenTurnActive] = "Talking during turn mechanics not available",
|
||||
[UnitActionErrorType.ThisUnitCantMove] = "This unit can't do Move action",
|
||||
[UnitActionErrorType.ThisUnitCantAttack] = "This unit can't do Attack action",
|
||||
[UnitActionErrorType.ThisUnitCantUse] = "This unit can't do Use action",
|
||||
[UnitActionErrorType.ThisUnitCantTalk] = "This unit can't do Talk action",
|
||||
[UnitActionErrorType.ThisUnitCantTake] = "This unit can't do Take action",
|
||||
[UnitActionErrorType.ThisUnitCantInspect] = "This unit can't do Inspect action",
|
||||
[UnitActionErrorType.OtherUnitCantBeInspected] = "Other unit can't be Inspected",
|
||||
[UnitActionErrorType.OtherUnitCantBeTalked] = "Other unit can't be Talked with",
|
||||
};
|
||||
|
||||
public static string Get(UnitActionErrorType errorType)
|
||||
{
|
||||
return Messages.GetValueOrDefault(errorType, errorType.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 751eee10c5954993b708a8ec5bea1b6b
|
||||
timeCreated: 1698959051
|
||||
@@ -0,0 +1,49 @@
|
||||
namespace VOID.Generic.Objects.Unit.Actions.Exceptions
|
||||
{
|
||||
public enum UnitActionErrorType
|
||||
{
|
||||
ActionStateIsNotReady,
|
||||
NotInRange,
|
||||
UnitStateIsNotControllable,
|
||||
UnitDontCarryThatItem,
|
||||
UnitDontWearThatItem,
|
||||
ItemIsNotOnGround,
|
||||
RequirementsNotMeetToEquipThatItem,
|
||||
CannotEquipItemInThatSlot,
|
||||
RequirementsNotMeetToUseThatItem,
|
||||
RequirementsNotMeetToUseThatAbility,
|
||||
WrongNumberOfTargetsToUseThatAbility,
|
||||
WrongTargetsSelectedToUseThatAbility,
|
||||
UnEquipIsPrevented,
|
||||
DropIsPrevented,
|
||||
EquipIsPrevented,
|
||||
PickIsPrevented,
|
||||
UseIsPrevented,
|
||||
ContainerIsNotOpenedByThisUnit,
|
||||
ItemIsNotMovable,
|
||||
ItemIsNotPickable,
|
||||
AbilityIsPrevented,
|
||||
AbilityHitIsPrevented,
|
||||
UsableNotEnoughStacks,
|
||||
PreviousActionNotFinished,
|
||||
UnitNotInTurnManager,
|
||||
UnitSelfTurnNotActive,
|
||||
UnitNotEnoughActionPoints,
|
||||
UnitNotEnoughMovePoints,
|
||||
TalkNotAvailableWhenTurnActive,
|
||||
ContainerIsAlreadyOpenedByThisUnit,
|
||||
EnemiesAreTooClose,
|
||||
OtherUnitIsNotOpenedByThisUnit,
|
||||
OtherUnitIsAlreadyOpenedByThisUnit,
|
||||
NoPathToTarget,
|
||||
ThisUnitCantMove,
|
||||
ThisUnitCantAttack,
|
||||
ThisUnitCantUse,
|
||||
ThisUnitCantTalk,
|
||||
ThisUnitCantTake,
|
||||
ThisUnitCantInspect,
|
||||
OtherUnitCantBeInspected,
|
||||
OtherUnitCantBeTalked,
|
||||
ThisUnitIsCasting
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29d18411212c41ccbbebd94f8ff33538
|
||||
timeCreated: 1686666706
|
||||
@@ -0,0 +1,88 @@
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Objects.Item;
|
||||
using VOID.Generic.Objects.Item.Events;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Wearable;
|
||||
using VOID.Generic.Objects.Wearable.Events;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class ForcedDropAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly ItemObject _item;
|
||||
private readonly Vector3 _dropPosition;
|
||||
|
||||
public ForcedDropAction(UnitObject unit, ItemObject item)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
_dropPosition = unit.transform.position;
|
||||
}
|
||||
|
||||
public ForcedDropAction(UnitObject unit, ItemObject item, Vector3 dropPosition)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
_dropPosition = dropPosition;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
Check(
|
||||
_item.itemState.carriedBy == _unit,
|
||||
UnitActionErrorType.UnitDontCarryThatItem);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
TryToUnEquip();
|
||||
|
||||
var dropEvent = new DropEvent
|
||||
{
|
||||
item = _item,
|
||||
unit = _unit
|
||||
};
|
||||
|
||||
_item.itemEvents.onDroppedBefore.Invoke(dropEvent);
|
||||
_unit.unitEvents.onDropBefore.Invoke(dropEvent);
|
||||
|
||||
BeforePerform();
|
||||
_unit.unitBackpack.Drop(_item);
|
||||
_item.transform.position = _dropPosition;
|
||||
_item.itemEvents.onDroppedAfter.Invoke(dropEvent);
|
||||
_unit.unitEvents.onDropAfter.Invoke(dropEvent);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
|
||||
private void TryToUnEquip()
|
||||
{
|
||||
if (_item is not WearableObject item) return;
|
||||
if (!item.wearableState.wearerUnit) return;
|
||||
|
||||
var unEquipEvent = new UnEquipEvent
|
||||
{
|
||||
wearable = item,
|
||||
unit = _unit
|
||||
};
|
||||
|
||||
item.wearableEvents.onUnEquippedBefore.Invoke(unEquipEvent);
|
||||
_unit.unitEvents.onUnEquipBefore.Invoke(unEquipEvent);
|
||||
|
||||
_unit.unitEquipment.UnEquip(item);
|
||||
_unit.unitBackpack.Take(item);
|
||||
|
||||
item.wearableEvents.onUnEquippedAfter.Invoke(unEquipEvent);
|
||||
_unit.unitEvents.onUnEquipAfter.Invoke(unEquipEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2ff2b3fa8644c2998c8ee9682e77aa4
|
||||
timeCreated: 1717965358
|
||||
@@ -0,0 +1,74 @@
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Item;
|
||||
using VOID.Generic.Objects.Item.Events;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class ForcedTakeAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly ItemObject _item;
|
||||
private readonly int _slotIndex;
|
||||
|
||||
public ForcedTakeAction(UnitObject unit, ItemObject item)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
}
|
||||
|
||||
public ForcedTakeAction(UnitObject unit, ItemObject item, int slotIndex) : this(unit, item)
|
||||
{
|
||||
_slotIndex = slotIndex;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
_unit.unitData.canTake,
|
||||
UnitActionErrorType.ThisUnitCantTake);
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
Check(
|
||||
_item.itemData.canBePicked && _item.itemData.canBeMoved,
|
||||
UnitActionErrorType.ItemIsNotPickable);
|
||||
Check(
|
||||
!_item.itemState.carriedBy,
|
||||
UnitActionErrorType.ItemIsNotOnGround);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
if (_unit.basicState.turnManager)
|
||||
_unit.unitData.UseResource(UnitResourceType.ActionPoints, 1);
|
||||
|
||||
var pickEvent = new PickEvent
|
||||
{
|
||||
item = _item,
|
||||
unit = _unit
|
||||
};
|
||||
|
||||
_item.itemEvents.onPickedBefore.Invoke(pickEvent);
|
||||
_unit.unitEvents.onTakeBefore.Invoke(pickEvent);
|
||||
|
||||
BeforePerform();
|
||||
if (_slotIndex != default)
|
||||
_unit.unitBackpack.Take(_slotIndex, _item);
|
||||
else
|
||||
_unit.unitBackpack.Take(_item);
|
||||
_item.itemEvents.onPickedAfter.Invoke(pickEvent);
|
||||
_unit.unitEvents.onTakeAfter.Invoke(pickEvent);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d90c417b2bb46fda4ece59b93cc9818
|
||||
timeCreated: 1717965568
|
||||
@@ -0,0 +1,63 @@
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Util;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class InspectAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly AbstractObject _targetObject;
|
||||
private bool _isInspectFinished;
|
||||
|
||||
public InspectAction(UnitObject unit, AbstractObject targetObject)
|
||||
{
|
||||
_unit = unit;
|
||||
_targetObject = targetObject;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
return RangeUtil.IsInRange(_unit, _targetObject, _unit.unitData.inspectRange);
|
||||
}
|
||||
|
||||
protected override void OnEndIt() { }
|
||||
|
||||
protected override void OnCancelIt() { }
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
_targetObject.basicData.canBeInspected,
|
||||
UnitActionErrorType.OtherUnitCantBeInspected);
|
||||
Check(
|
||||
_unit.unitData.canInspect,
|
||||
UnitActionErrorType.ThisUnitCantInspect);
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
}
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
new RotateAction(_unit, _targetObject).DoIt();
|
||||
BeforePerform();
|
||||
// Tutaj inspekcja
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f258e7d8f43c447ca7d1dcbacb9e467e
|
||||
timeCreated: 1666712540
|
||||
@@ -0,0 +1,46 @@
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class LeaveTurnAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
|
||||
public LeaveTurnAction(UnitObject unit)
|
||||
{
|
||||
_unit = unit;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
public override bool CanSkipQueue() => true;
|
||||
|
||||
protected override void OnEndIt()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnCancelIt()
|
||||
{
|
||||
}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
Check(
|
||||
_unit.basicState.turnManager,
|
||||
UnitActionErrorType.UnitNotInTurnManager);
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.basicState.turnManager.CanObjectExit(_unit),
|
||||
UnitActionErrorType.EnemiesAreTooClose);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
_unit.basicState.turnManager.ObjectExit(_unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 473562657fd14538ac05d1303664b527
|
||||
timeCreated: 1708521881
|
||||
@@ -0,0 +1,114 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Util;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class MoveAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly Vector3 _targetPosition;
|
||||
private readonly AbstractObject _targetObject;
|
||||
private readonly float _untilInRange;
|
||||
|
||||
public MoveAction(UnitObject unit, Vector3 targetPosition, float untilInRange = 0f)
|
||||
{
|
||||
_unit = unit;
|
||||
_targetPosition = targetPosition;
|
||||
_untilInRange = untilInRange;
|
||||
}
|
||||
|
||||
public MoveAction(UnitObject unit, AbstractObject targetObject, float untilInRange = 0f)
|
||||
: this(unit, targetObject.transform.position, untilInRange + targetObject.basicData.radius)
|
||||
{
|
||||
_targetObject = targetObject;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
// Dont let player ordering move too far away
|
||||
var distanceBetween = Vector3.Distance(_unit.transform.position, _targetPosition);
|
||||
return distanceBetween < 100f;
|
||||
}
|
||||
|
||||
public override bool CanBeStopped()
|
||||
{
|
||||
return !_unit.unitState.isTraversing;
|
||||
}
|
||||
|
||||
protected override void OnEndIt()
|
||||
{
|
||||
_unit.unitEvents.onMoveEnd.RemoveListener(OnMoveEnd);
|
||||
}
|
||||
|
||||
protected override void OnCancelIt()
|
||||
{
|
||||
_unit.unitEvents.onMoveEnd.RemoveListener(OnMoveEnd);
|
||||
_unit.unitNavAgent.Stop();
|
||||
}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
_unit.unitData.canMove,
|
||||
UnitActionErrorType.ThisUnitCantMove);
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
Check(
|
||||
!_unit.unitState.isCasting,
|
||||
UnitActionErrorType.ThisUnitIsCasting);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.unitData.currentResources.movePoints > 0.1f,
|
||||
UnitActionErrorType.UnitNotEnoughMovePoints);
|
||||
}
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
_unit.unitNavAgent.CalculatePathTo(_targetPosition, _untilInRange);
|
||||
Check(
|
||||
_unit.unitNavAgent.GetPath().status is not NavMeshPathStatus.PathInvalid,
|
||||
UnitActionErrorType.NoPathToTarget);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
var isInRange = _targetObject
|
||||
? RangeUtil.IsInRange(_unit, _targetObject, _untilInRange, false)
|
||||
: RangeUtil.IsInRange(_unit, _targetPosition, _untilInRange, false);
|
||||
|
||||
if (isInRange)
|
||||
{
|
||||
EndIt();
|
||||
return;
|
||||
}
|
||||
|
||||
BeforePerform();
|
||||
|
||||
_unit.unitEvents.onMoveEnd.AddListener(OnMoveEnd);
|
||||
var moveStarted = _targetObject
|
||||
? _unit.unitNavAgent.Move(_targetObject, _untilInRange)
|
||||
: _unit.unitNavAgent.Move(_targetPosition, _untilInRange);
|
||||
|
||||
// Unit didn't move for some reason (usually path is impossible or already at path destination)
|
||||
if (!moveStarted) EndIt();
|
||||
}
|
||||
|
||||
private void OnMoveEnd(MoveEvent moveEvent)
|
||||
{
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d481a211739c4caa88711e3ae6bbef5d
|
||||
timeCreated: 1666646839
|
||||
@@ -0,0 +1,86 @@
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Item;
|
||||
using VOID.Generic.Objects.Item.Events;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Util;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class MoveItemAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly ItemObject _item;
|
||||
private readonly Vector3 _toPosition;
|
||||
|
||||
public MoveItemAction(UnitObject unit, ItemObject item, Vector3 toPosition)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
_toPosition = toPosition;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
return RangeUtil.IsInRange(_unit, _item, _unit.unitData.takeRange)
|
||||
&& RangeUtil.IsInRange(_item, _toPosition, _unit.unitData.takeRange*2);
|
||||
}
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.unitData.currentResources.actionPoints >= 1,
|
||||
UnitActionErrorType.UnitNotEnoughActionPoints);
|
||||
}
|
||||
Check(
|
||||
_item.itemData.canBeMoved,
|
||||
UnitActionErrorType.ItemIsNotMovable);
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
if (_unit.basicState.turnManager)
|
||||
_unit.unitData.UseResource(UnitResourceType.ActionPoints, 1);
|
||||
|
||||
var moveItemEvent = new MoveItemEvent
|
||||
{
|
||||
unit = _unit,
|
||||
item = _item,
|
||||
fromPosition = _item.transform.position,
|
||||
toPosition = _toPosition,
|
||||
};
|
||||
|
||||
_item.itemEvents.onMovedBefore.Invoke(moveItemEvent);
|
||||
_unit.unitEvents.onMoveItemBefore.Invoke(moveItemEvent);
|
||||
|
||||
_unit.OrderInstantly(new RotateAction(_unit, _item));
|
||||
BeforePerform();
|
||||
|
||||
Check(_item.Move(_toPosition), UnitActionErrorType.ItemIsNotMovable);
|
||||
|
||||
_item.itemEvents.onMovedAfter.Invoke(moveItemEvent);
|
||||
_unit.unitEvents.onMoveItemAfter.Invoke(moveItemEvent);
|
||||
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 56e325e16de846e08d48376bb2d31e28
|
||||
timeCreated: 1694902221
|
||||
@@ -0,0 +1,68 @@
|
||||
using VOID.Generic.Objects.Container;
|
||||
using VOID.Generic.Objects.Container.Events;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Util;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class OpenContainerAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly ContainerObject _container;
|
||||
|
||||
public OpenContainerAction(UnitObject unit, ContainerObject container)
|
||||
{
|
||||
_unit = unit;
|
||||
_container = container;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
return RangeUtil.IsInRange(_unit, _container, _unit.unitData.takeRange);
|
||||
}
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn || _container.itemState.carriedBy == _unit,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
}
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
Check(
|
||||
!_container.containerState.openedBy.Contains(_unit),
|
||||
UnitActionErrorType.ContainerIsAlreadyOpenedByThisUnit);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
var containerOpenEvent = new ContainerOpenEvent
|
||||
{
|
||||
openedBy = _unit,
|
||||
container = _container
|
||||
};
|
||||
|
||||
if (_container.itemState.carriedBy != _unit)
|
||||
_unit.OrderInstantly(new RotateAction(_unit, _container));
|
||||
|
||||
BeforePerform();
|
||||
_container.containerEvents.onOpen.Invoke(containerOpenEvent);
|
||||
_unit.unitEvents.onContainerOpen.Invoke(containerOpenEvent);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53552ef81c0c4845afac57174071db3a
|
||||
timeCreated: 1694902221
|
||||
@@ -0,0 +1,69 @@
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Util;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class OpenOtherUnitAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly UnitObject _otherUnit;
|
||||
|
||||
public OpenOtherUnitAction(UnitObject unit, UnitObject otherUnit)
|
||||
{
|
||||
_unit = unit;
|
||||
_otherUnit = otherUnit;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
return RangeUtil.IsInRange(_unit, _otherUnit, _unit.unitData.takeRange);
|
||||
}
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
}
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
Check(
|
||||
_otherUnit.basicState.isDead,
|
||||
UnitActionErrorType.NotInRange);
|
||||
Check(
|
||||
!_otherUnit.unitState.openedBy.Contains(_unit),
|
||||
UnitActionErrorType.OtherUnitIsAlreadyOpenedByThisUnit);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
var openOtherUnitEvent = new OpenOtherUnitEvent()
|
||||
{
|
||||
openedBy = _unit,
|
||||
otherUnit = _otherUnit
|
||||
};
|
||||
|
||||
_unit.OrderInstantly(new RotateAction(_unit, _otherUnit));
|
||||
|
||||
BeforePerform();
|
||||
_otherUnit.unitEvents.onOpenedByOtherUnit.Invoke(openOtherUnitEvent);
|
||||
_unit.unitEvents.onOpenOtherUnit.Invoke(openOtherUnitEvent);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6544441f582a408a99a829faa559acb7
|
||||
timeCreated: 1717947141
|
||||
@@ -0,0 +1,53 @@
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class RotateAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly float _targetYaw;
|
||||
|
||||
public RotateAction(UnitObject unit, float targetYaw)
|
||||
{
|
||||
_unit = unit;
|
||||
_targetYaw = targetYaw;
|
||||
}
|
||||
|
||||
public RotateAction(UnitObject unit, Vector3 lookAt)
|
||||
{
|
||||
_unit = unit;
|
||||
_targetYaw = Vector3.SignedAngle(
|
||||
Vector3.forward,
|
||||
Vector3.Scale(lookAt - unit.transform.position, new Vector3(1,0,1)),
|
||||
Vector3.up);
|
||||
}
|
||||
|
||||
public RotateAction(UnitObject unit, AbstractObject lookAt) : this(unit, lookAt.transform.position) { }
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
public override bool CanSkipQueue() => true;
|
||||
|
||||
protected override void OnEndIt() { }
|
||||
|
||||
protected override void OnCancelIt() { }
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
BeforePerform();
|
||||
var targetRotation = _unit.transform.rotation.eulerAngles;
|
||||
targetRotation.y = _targetYaw;
|
||||
_unit.transform.rotation = Quaternion.Euler(targetRotation);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e83a38e3a7c34f959bfe53f430c23dae
|
||||
timeCreated: 1696077331
|
||||
@@ -0,0 +1,105 @@
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Item;
|
||||
using VOID.Generic.Objects.Item.Events;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Util;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class TakeAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly ItemObject _item;
|
||||
private readonly int _slotIndex;
|
||||
|
||||
public TakeAction(UnitObject unit, ItemObject item)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
}
|
||||
|
||||
public TakeAction(UnitObject unit, ItemObject item, int slotIndex) : this(unit, item)
|
||||
{
|
||||
_slotIndex = slotIndex;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
return RangeUtil.IsInRange(_unit, _item, _unit.unitData.takeRange);
|
||||
}
|
||||
|
||||
protected override void OnEndIt()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnCancelIt()
|
||||
{
|
||||
}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
_unit.unitData.canTake,
|
||||
UnitActionErrorType.ThisUnitCantTake);
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.unitData.currentResources.actionPoints >= 1,
|
||||
UnitActionErrorType.UnitNotEnoughActionPoints);
|
||||
}
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
_item.itemData.canBePicked && _item.itemData.canBeMoved,
|
||||
UnitActionErrorType.ItemIsNotPickable);
|
||||
Check(
|
||||
!_item.itemState.carriedBy || _item.itemState.carriedBy.basicState.isDead,
|
||||
UnitActionErrorType.ItemIsNotOnGround);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
if (_unit.basicState.turnManager)
|
||||
_unit.unitData.UseResource(UnitResourceType.ActionPoints, 1);
|
||||
|
||||
_unit.OrderInstantly(new RotateAction(_unit, _item));
|
||||
|
||||
if (_item.itemState.carriedBy && _item.itemState.carriedBy.basicState.isDead)
|
||||
new ForcedDropAction(_item.itemState.carriedBy, _item).DoIt();
|
||||
|
||||
Check(!_item.itemState.carriedBy, UnitActionErrorType.ItemIsNotOnGround);
|
||||
|
||||
var pickEvent = new PickEvent
|
||||
{
|
||||
item = _item,
|
||||
unit = _unit
|
||||
};
|
||||
|
||||
_item.itemEvents.onPickedBefore.Invoke(pickEvent);
|
||||
_unit.unitEvents.onTakeBefore.Invoke(pickEvent);
|
||||
|
||||
Check(!pickEvent.prevented, UnitActionErrorType.PickIsPrevented);
|
||||
|
||||
BeforePerform();
|
||||
|
||||
if (_item.itemState.inContainer) _item.itemState.inContainer.containerContent.MoveOut(_item, _unit);
|
||||
|
||||
_unit.unitBackpack.Take(_slotIndex, _item);
|
||||
_item.itemEvents.onPickedAfter.Invoke(pickEvent);
|
||||
_unit.unitEvents.onTakeAfter.Invoke(pickEvent);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b1c26cd2b2449c6b6b692acac0d944a
|
||||
timeCreated: 1666711181
|
||||
@@ -0,0 +1,62 @@
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Util;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class TalkAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly UnitObject _targetObject;
|
||||
|
||||
public TalkAction(UnitObject unit, UnitObject targetObject)
|
||||
{
|
||||
_unit = unit;
|
||||
_targetObject = targetObject;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
return RangeUtil.IsInRange(_unit, _targetObject, _unit.unitData.talkRange);
|
||||
}
|
||||
|
||||
protected override void OnEndIt() { }
|
||||
|
||||
protected override void OnCancelIt() { }
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
_unit.unitData.canTalk,
|
||||
UnitActionErrorType.ThisUnitCantTalk);
|
||||
Check(
|
||||
_targetObject.unitData.canBeTalked,
|
||||
UnitActionErrorType.OtherUnitCantBeTalked);
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
Check(
|
||||
!_unit.basicState.turnManager,
|
||||
UnitActionErrorType.TalkNotAvailableWhenTurnActive);
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
new RotateAction(_unit, _targetObject).DoIt();
|
||||
BeforePerform();
|
||||
// Tutaj rozmowa
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 803ece80d3c045f980bc5ccf346cc211
|
||||
timeCreated: 1666711074
|
||||
@@ -0,0 +1,73 @@
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Item.Events;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Wearable;
|
||||
using VOID.Generic.Objects.Wearable.Events;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class UnEquipAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly WearableObject _item;
|
||||
|
||||
public UnEquipAction(UnitObject unit, WearableObject item)
|
||||
{
|
||||
_unit = unit;
|
||||
_item = item;
|
||||
}
|
||||
|
||||
public override bool IsInRange() => true;
|
||||
|
||||
protected override void OnEndIt() {}
|
||||
|
||||
protected override void OnCancelIt() {}
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.unitData.currentResources.actionPoints >= 1,
|
||||
UnitActionErrorType.UnitNotEnoughActionPoints);
|
||||
}
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
_item.wearableState.wearerUnit == _unit,
|
||||
UnitActionErrorType.UnitDontWearThatItem);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
if (_unit.basicState.turnManager)
|
||||
_unit.unitData.UseResource(UnitResourceType.ActionPoints, 1);
|
||||
|
||||
var unEquipEvent = new UnEquipEvent
|
||||
{
|
||||
wearable = _item,
|
||||
unit = _unit
|
||||
};
|
||||
|
||||
_item.wearableEvents.onUnEquippedBefore.Invoke(unEquipEvent);
|
||||
_unit.unitEvents.onUnEquipBefore.Invoke(unEquipEvent);
|
||||
|
||||
Check(!unEquipEvent.prevented, UnitActionErrorType.UnEquipIsPrevented);
|
||||
|
||||
BeforePerform();
|
||||
_unit.unitEquipment.UnEquip(_item);
|
||||
_unit.unitBackpack.Take(_item);
|
||||
_item.wearableEvents.onUnEquippedAfter.Invoke(unEquipEvent);
|
||||
_unit.unitEvents.onUnEquipAfter.Invoke(unEquipEvent);
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14701689e25d4ce2830058af6f2aa35d
|
||||
timeCreated: 1672747135
|
||||
@@ -0,0 +1,126 @@
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
using VOID.Generic.Objects.Door;
|
||||
using VOID.Generic.Objects.Item;
|
||||
using VOID.Generic.Objects.Unit.Actions.Exceptions;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Objects.Usable;
|
||||
using VOID.Generic.Objects.Usable.Events;
|
||||
using VOID.Generic.Util;
|
||||
using VOID.ScriptableObjects;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Actions
|
||||
{
|
||||
public class UseAction : AbstractAction
|
||||
{
|
||||
private readonly UnitObject _unit;
|
||||
private readonly AbstractObject _targetObject;
|
||||
|
||||
public UseAction(UnitObject unit, AbstractObject targetObject)
|
||||
{
|
||||
_unit = unit;
|
||||
_targetObject = targetObject;
|
||||
}
|
||||
|
||||
public override bool IsInRange()
|
||||
{
|
||||
return RangeUtil.IsInRange(_unit, _targetObject, _unit.unitData.useRange);
|
||||
}
|
||||
|
||||
protected override void OnEndIt() { }
|
||||
|
||||
protected override void OnCancelIt() { }
|
||||
|
||||
public override void CanDoIt()
|
||||
{
|
||||
Check(
|
||||
_unit.unitData.canUse,
|
||||
UnitActionErrorType.ThisUnitCantUse);
|
||||
Check(
|
||||
state == ActionState.Ready,
|
||||
UnitActionErrorType.ActionStateIsNotReady);
|
||||
if (_unit.basicState.turnManager)
|
||||
{
|
||||
Check(
|
||||
_unit.unitState.isSelfTurn,
|
||||
UnitActionErrorType.UnitSelfTurnNotActive);
|
||||
Check(
|
||||
_unit.unitData.currentResources.actionPoints >= 1,
|
||||
UnitActionErrorType.UnitNotEnoughActionPoints);
|
||||
}
|
||||
Check(
|
||||
_unit.unitState.isControllable,
|
||||
UnitActionErrorType.UnitStateIsNotControllable);
|
||||
Check(
|
||||
IsInRange(),
|
||||
UnitActionErrorType.NotInRange);
|
||||
Check(
|
||||
_targetObject is not UsableObject usable || usable.usableData.requirements.All(requirement => requirement.Check(_unit)),
|
||||
UnitActionErrorType.RequirementsNotMeetToUseThatItem);
|
||||
}
|
||||
|
||||
protected override void OnDoIt()
|
||||
{
|
||||
if (_unit.basicState.turnManager)
|
||||
_unit.unitData.UseResource(UnitResourceType.ActionPoints, 1);
|
||||
|
||||
if (_targetObject is not ItemObject item || item.itemState.carriedBy != _unit)
|
||||
_unit.OrderInstantly(new RotateAction(_unit, _targetObject));
|
||||
|
||||
BeforePerform();
|
||||
switch (_targetObject)
|
||||
{
|
||||
case UsableObject usable:
|
||||
UseUsable(usable);
|
||||
break;
|
||||
case DoorObject door:
|
||||
UseDoor(door);
|
||||
break;
|
||||
default:
|
||||
Debug.LogWarning($"Object '{nameof(_targetObject)}' cant be used.");
|
||||
break;
|
||||
}
|
||||
|
||||
AfterPerform();
|
||||
EndIt();
|
||||
}
|
||||
|
||||
private void UseUsable(UsableObject usable)
|
||||
{
|
||||
var useEvent = new UseEvent
|
||||
{
|
||||
usedBy = _unit,
|
||||
usedObject = usable
|
||||
};
|
||||
|
||||
Check(usable.itemData.stackSize >= usable.usableData.stacksPerUse, UnitActionErrorType.UsableNotEnoughStacks);
|
||||
|
||||
useEvent.usedBy.unitEvents.onUseBefore.Invoke(useEvent);
|
||||
useEvent.usedObject.usableEvents.onUsedBefore.Invoke(useEvent);
|
||||
|
||||
Check(!useEvent.prevented, UnitActionErrorType.UseIsPrevented);
|
||||
|
||||
var equipStatus = ScriptableObject.CreateInstance<BasicStatus>();
|
||||
equipStatus.effects = usable.usableData.applyOnUse;
|
||||
equipStatus.hidden = true;
|
||||
_unit.statusManager.AddStatus(equipStatus, _unit, false);
|
||||
|
||||
useEvent.usedBy.unitEvents.onUseAfter.Invoke(useEvent);
|
||||
useEvent.usedObject.usableEvents.onUsedAfter.Invoke(useEvent);
|
||||
|
||||
usable.itemData.stackSize -= usable.usableData.stacksPerUse;
|
||||
|
||||
if (usable.itemData.stackSize <= 0) usable.Remove();
|
||||
}
|
||||
|
||||
private void UseDoor(DoorObject door)
|
||||
{
|
||||
if (door.doorState.isOpen)
|
||||
door.Close(_unit);
|
||||
else
|
||||
door.Open(_unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a8ad83743854805ac80ebe801e80a0a
|
||||
timeCreated: 1666710459
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5909842c0d6b4c6bbfb45d9db49b36d5
|
||||
timeCreated: 1667422160
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Animations
|
||||
{
|
||||
[Serializable]
|
||||
public class ActionAnimation
|
||||
{
|
||||
[Required] public AnimationClip clip;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5babdf50db1449968ec3e18055128f10
|
||||
timeCreated: 1739299051
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Animations
|
||||
{
|
||||
[Serializable]
|
||||
public class ActionLoopAnimation
|
||||
{
|
||||
public AnimationClip startClip;
|
||||
[Required] public AnimationClip loopClip;
|
||||
public AnimationClip endClip;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab1941c1623c4d76836ab79ae93f0972
|
||||
timeCreated: 1739299081
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4202d6dc9d38401bba96287bbf88de41
|
||||
timeCreated: 1741290808
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations.Rigging;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Animations.Helpers
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[AddComponentMenu("Animation Rigging/Extract Transform Constraint")]
|
||||
|
||||
public class ExtractTransformConstraint : RigConstraint<
|
||||
ExtractTransformConstraintJob,
|
||||
ExtractTransformConstraintData,
|
||||
ExtractTransformConstraintJobBinder>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5141e0508a048359f47d054e1f893f9
|
||||
timeCreated: 1741290865
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations.Rigging;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Animations.Helpers
|
||||
{
|
||||
[Serializable]
|
||||
public struct ExtractTransformConstraintData : IAnimationJobData
|
||||
{
|
||||
[SyncSceneToStream] public Transform bone;
|
||||
|
||||
public Vector3 position;
|
||||
public Quaternion rotation;
|
||||
|
||||
public bool IsValid()
|
||||
{
|
||||
return bone != null;
|
||||
}
|
||||
|
||||
public void SetDefaultValues()
|
||||
{
|
||||
this.bone = null;
|
||||
|
||||
this.position = Vector3.zero;
|
||||
this.rotation = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93d692f5ab8246a09f9c272bab22296e
|
||||
timeCreated: 1741290854
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations;
|
||||
using UnityEngine.Animations.Rigging;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Animations.Helpers
|
||||
{
|
||||
public struct ExtractTransformConstraintJob : IWeightedAnimationJob
|
||||
{
|
||||
public ReadWriteTransformHandle bone;
|
||||
|
||||
public FloatProperty jobWeight { get; set; }
|
||||
|
||||
public Vector3Property position;
|
||||
public Vector4Property rotation;
|
||||
|
||||
public void ProcessRootMotion(AnimationStream stream)
|
||||
{ }
|
||||
|
||||
public void ProcessAnimation(AnimationStream stream)
|
||||
{
|
||||
AnimationRuntimeUtils.PassThrough(stream, this.bone);
|
||||
|
||||
var pos = this.bone.GetPosition(stream);
|
||||
var rot = this.bone.GetRotation(stream);
|
||||
|
||||
this.position.Set(stream, pos);
|
||||
this.rotation.Set(stream, new Vector4(rot.x, rot.y, rot.z, rot.w));
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31e85282774544ca90f09d7cfb94503d
|
||||
timeCreated: 1741290825
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations.Rigging;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Animations.Helpers
|
||||
{
|
||||
public class ExtractTransformConstraintJobBinder : AnimationJobBinder<
|
||||
ExtractTransformConstraintJob,
|
||||
ExtractTransformConstraintData>
|
||||
{
|
||||
public override ExtractTransformConstraintJob Create(Animator animator,
|
||||
ref ExtractTransformConstraintData data, Component component)
|
||||
{
|
||||
return new ExtractTransformConstraintJob
|
||||
{
|
||||
bone = ReadWriteTransformHandle.Bind(animator, data.bone),
|
||||
position = Vector3Property.Bind(animator, component, "m_Data." + nameof(data.position)),
|
||||
rotation = Vector4Property.Bind(animator, component, "m_Data." + nameof(data.rotation))
|
||||
};
|
||||
}
|
||||
|
||||
public override void Destroy(ExtractTransformConstraintJob job)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3126a4f55234624853818c555c65eef
|
||||
timeCreated: 1741290841
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Animations
|
||||
{
|
||||
/// <summary>
|
||||
/// Little hacky trick to make traversal root motion animation ALWAYS move by identical distance.
|
||||
///
|
||||
/// Requirements:
|
||||
/// 1. Attach this to start/loop/end states in animator
|
||||
/// 2. Transitions should have as small as possible exit time, less than 0.1 (0.0 would be best)
|
||||
/// </summary>
|
||||
public class MatchTargetTraversalStateHelper : StateMachineBehaviour
|
||||
{
|
||||
private bool _didMatchTarget;
|
||||
private Vector3 _startPosition;
|
||||
|
||||
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||
{
|
||||
_didMatchTarget = false;
|
||||
_startPosition = animator.transform.position;
|
||||
}
|
||||
|
||||
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||
{
|
||||
if (animator.GetCurrentAnimatorStateInfo(layerIndex).fullPathHash != stateInfo.fullPathHash) return;
|
||||
if (_didMatchTarget) return;
|
||||
|
||||
_didMatchTarget = true;
|
||||
var clip = animator.GetCurrentAnimatorClipInfo(layerIndex)[0].clip;
|
||||
var clipOffset = animator.transform.TransformDirection(clip.length * clip.averageSpeed);
|
||||
var repeat = clip.isLooping ? 100 : 1;
|
||||
animator.MatchTarget(
|
||||
_startPosition + clipOffset*repeat,
|
||||
Quaternion.identity,
|
||||
AvatarTarget.Root,
|
||||
new MatchTargetWeightMask(Vector3.one, 0),
|
||||
stateInfo.normalizedTime,
|
||||
repeat
|
||||
);
|
||||
}
|
||||
|
||||
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
||||
{
|
||||
animator.InterruptMatchTarget(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12a4be4ce958473d872afb306a62a3bd
|
||||
timeCreated: 1745524280
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Animations
|
||||
{
|
||||
[RequireComponent(typeof(Animator))]
|
||||
public class UnitAnimatorCallbacks : MonoBehaviour
|
||||
{
|
||||
public event Action<AnimationEvent> OnAnimationEvent;
|
||||
public event Action OnApplyRootMotion;
|
||||
|
||||
private void OnStart(AnimationEvent animationEvent) => OnAnimationEvent?.Invoke(animationEvent);
|
||||
private void OnLoopStart(AnimationEvent animationEvent) => OnAnimationEvent?.Invoke(animationEvent);
|
||||
private void OnPerform(AnimationEvent animationEvent) => OnAnimationEvent?.Invoke(animationEvent);
|
||||
private void OnLoopEnd(AnimationEvent animationEvent) => OnAnimationEvent?.Invoke(animationEvent);
|
||||
private void OnEnd(AnimationEvent animationEvent) => OnAnimationEvent?.Invoke(animationEvent);
|
||||
|
||||
private void FootL() {}
|
||||
private void FootR() {}
|
||||
|
||||
private void OnAnimatorMove() => OnApplyRootMotion?.Invoke();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef0871046f0ce95458fe7d62724b7e5f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30ecc704f4b14426b9ce76b37e81eb94
|
||||
timeCreated: 1693747247
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using VOID.Generic.Dict;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Data
|
||||
{
|
||||
[Serializable]
|
||||
public record MainAttributes
|
||||
{
|
||||
[MinValue(1f)] public int strength = 5;
|
||||
[MinValue(1f)] public int dexterity = 5;
|
||||
[MinValue(1f)] public int intelligence = 5;
|
||||
[MinValue(1f)] public int constitution = 5;
|
||||
[MinValue(1f)] public int speed = 5;
|
||||
[MinValue(1f)] public int perception = 5;
|
||||
|
||||
public int Get(MainAttributeType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
MainAttributeType.Strength => strength,
|
||||
MainAttributeType.Dexterity => dexterity,
|
||||
MainAttributeType.Intelligence => intelligence,
|
||||
MainAttributeType.Constitution => constitution,
|
||||
MainAttributeType.Speed => speed,
|
||||
MainAttributeType.Perception => perception,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
|
||||
};
|
||||
}
|
||||
|
||||
public void Set(MainAttributeType type, int value)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case MainAttributeType.Strength: strength = value; return;
|
||||
case MainAttributeType.Dexterity: dexterity = value; return;
|
||||
case MainAttributeType.Intelligence: intelligence = value; return;
|
||||
case MainAttributeType.Constitution: constitution = value; return;
|
||||
case MainAttributeType.Speed: speed = value; return;
|
||||
case MainAttributeType.Perception: perception = value; return;
|
||||
default: throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86c039ddbb434e77998688732f100389
|
||||
timeCreated: 1693753877
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using VOID.Generic.Dict;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Data
|
||||
{
|
||||
[Serializable]
|
||||
public record SubAttributes
|
||||
{
|
||||
[MinValue(1f)] public int damageMin = 1;
|
||||
[MinValue(1f)] public int damageMax = 1;
|
||||
[MinValue(0f)] public float criticalDamageChance = 0f;
|
||||
[MinValue(0f)] public float criticalDamageMultiplier = 2f;
|
||||
public float accuracy = 0.6f;
|
||||
public float dodge = 0.05f;
|
||||
[MinValue(0f)] public float carryCapacity = 50f;
|
||||
[MinValue(0f)] public float sight = 0f;
|
||||
[MinValue(0f)] public float hear = 0f;
|
||||
[MinValue(0f)] public float move = 0f;
|
||||
public float initiative = 0f;
|
||||
|
||||
public float Get(SubAttributeType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
SubAttributeType.DamageMin => damageMin,
|
||||
SubAttributeType.DamageMax => damageMax,
|
||||
SubAttributeType.CriticalDamageChance => criticalDamageChance,
|
||||
SubAttributeType.CriticalDamageMultiplier => criticalDamageMultiplier,
|
||||
SubAttributeType.Accuracy => accuracy,
|
||||
SubAttributeType.Dodge => dodge,
|
||||
SubAttributeType.CarryCapacity => carryCapacity,
|
||||
SubAttributeType.Sight => sight,
|
||||
SubAttributeType.Hear => hear,
|
||||
SubAttributeType.Move => move,
|
||||
SubAttributeType.Initiative => initiative,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
|
||||
};
|
||||
}
|
||||
|
||||
public void Set(SubAttributeType type, float value)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case SubAttributeType.DamageMin: damageMin = (int)value; return;
|
||||
case SubAttributeType.DamageMax: damageMax = (int)value; return;
|
||||
case SubAttributeType.CriticalDamageChance: criticalDamageChance = value; return;
|
||||
case SubAttributeType.CriticalDamageMultiplier: criticalDamageMultiplier = value; return;
|
||||
case SubAttributeType.Accuracy: accuracy = value; return;
|
||||
case SubAttributeType.Dodge: dodge = value; return;
|
||||
case SubAttributeType.CarryCapacity: carryCapacity = value; return;
|
||||
case SubAttributeType.Sight: sight = value; return;
|
||||
case SubAttributeType.Hear: hear = value; return;
|
||||
case SubAttributeType.Move: move = value; return;
|
||||
case SubAttributeType.Initiative: initiative = value; return;
|
||||
default: throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a04b60a1cc1845c185ea523f11bfa8ed
|
||||
timeCreated: 1693754300
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using VOID.Generic.Dict;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Data
|
||||
{
|
||||
[Serializable]
|
||||
public record UnitResources
|
||||
{
|
||||
[MinValue(0f)] public float actionPoints = 2f;
|
||||
[MinValue(0f)] public float movePoints = 0f;
|
||||
|
||||
public float Get(UnitResourceType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
UnitResourceType.ActionPoints => actionPoints,
|
||||
UnitResourceType.MovePoints => movePoints,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
|
||||
};
|
||||
}
|
||||
|
||||
public void Set(UnitResourceType type, float value)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case UnitResourceType.ActionPoints: actionPoints = value; return;
|
||||
case UnitResourceType.MovePoints: movePoints = value; return;
|
||||
default: throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8c212010f644721acbb0178154616e6
|
||||
timeCreated: 1693747302
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8799873ad494470e86cc0596ec0b832c
|
||||
timeCreated: 1698421195
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.Utilities;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Abstract.Events;
|
||||
using VOID.Generic.Status.Effect;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.DataCalculator
|
||||
{
|
||||
public class BasicResourceCalcGroup : ICalcGroup
|
||||
{
|
||||
public string GetMarkerGroup()
|
||||
{
|
||||
return "BasicResource";
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetMarkerItems()
|
||||
{
|
||||
return GetEnums().Select(@enum => @enum.ToString());
|
||||
}
|
||||
|
||||
public Type GetEnumType()
|
||||
{
|
||||
return typeof(BasicResourceType);
|
||||
}
|
||||
|
||||
public IEnumerable<Enum> GetEnums()
|
||||
{
|
||||
return Enum.GetValues(GetEnumType()).OfType<Enum>();
|
||||
}
|
||||
|
||||
public Enum GetEnum(string markerItem)
|
||||
{
|
||||
return Enum.Parse<BasicResourceType>(markerItem, true);
|
||||
}
|
||||
|
||||
public float GetEffectValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
var @enum = Enum.Parse<BasicResourceType>(markerItem, true);
|
||||
return unit.statusManager.GetStatuses()
|
||||
.SelectMany(status => status.effects)
|
||||
.FilterCast<PointChangeBasicResourceEffect>()
|
||||
.Where(effect => effect.basicResourceType == @enum)
|
||||
.Select(effect => effect.pointModificator)
|
||||
.Sum();
|
||||
}
|
||||
|
||||
public float GetBaseValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
return unit.basicData.baseMaxResources.Get(Enum.Parse<BasicResourceType>(markerItem, true));
|
||||
}
|
||||
|
||||
public float GetValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
return unit.basicData.maxResources.Get(Enum.Parse<BasicResourceType>(markerItem, true));
|
||||
}
|
||||
|
||||
public void UpdateWithValue(UnitObject unit, string markerItem, float formulaValue)
|
||||
{
|
||||
var @enum = Enum.Parse<BasicResourceType>(markerItem, true);
|
||||
var baseValue = GetBaseValue(unit, markerItem);
|
||||
var effectValue = GetEffectValue(unit, markerItem);
|
||||
var previousValue = GetValue(unit, markerItem);
|
||||
var newValue = baseValue + effectValue + formulaValue;
|
||||
var diffValue = newValue - previousValue;
|
||||
unit.basicData.maxResources.Set(@enum, newValue);
|
||||
|
||||
unit.basicEvents.onMaxResourceChange.Invoke(
|
||||
new BasicResourceChangeEvent()
|
||||
{
|
||||
obj = unit,
|
||||
type = @enum,
|
||||
changedValue = diffValue,
|
||||
newValue = newValue,
|
||||
oldValue = previousValue
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a750f18ecb744591a6a96b27370d8332
|
||||
timeCreated: 1698434766
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.DataCalculator
|
||||
{
|
||||
public interface ICalcGroup
|
||||
{
|
||||
public string GetMarkerGroup();
|
||||
public IEnumerable<string> GetMarkerItems();
|
||||
public Type GetEnumType();
|
||||
public IEnumerable<Enum> GetEnums();
|
||||
public Enum GetEnum(string markerItem);
|
||||
|
||||
public bool CheckMarker(string markerGroup, string markerItem)
|
||||
{
|
||||
return GetMarkerGroup().Equals(markerGroup, StringComparison.OrdinalIgnoreCase)
|
||||
&& GetMarkerItems().Contains(markerItem, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public bool CheckEnum(Enum @enum)
|
||||
{
|
||||
return GetEnums().Contains(@enum);
|
||||
}
|
||||
|
||||
public float GetEffectValue(UnitObject unit, string markerItem);
|
||||
public float GetBaseValue(UnitObject unit, string markerItem);
|
||||
public float GetValue(UnitObject unit, string markerItem);
|
||||
|
||||
public void UpdateWithValue(UnitObject unit, string markerItem, float formulaValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b1d48d0400f443e9ff037e00b079a9f
|
||||
timeCreated: 1698421311
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.Utilities;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Status.Effect;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.DataCalculator
|
||||
{
|
||||
public class MainAttributeCalcGroup : ICalcGroup
|
||||
{
|
||||
public string GetMarkerGroup()
|
||||
{
|
||||
return "MainAttribute";
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetMarkerItems()
|
||||
{
|
||||
return GetEnums().Select(@enum => @enum.ToString());
|
||||
}
|
||||
|
||||
public Type GetEnumType()
|
||||
{
|
||||
return typeof(MainAttributeType);
|
||||
}
|
||||
|
||||
public IEnumerable<Enum> GetEnums()
|
||||
{
|
||||
return Enum.GetValues(GetEnumType()).OfType<Enum>();
|
||||
}
|
||||
|
||||
public Enum GetEnum(string markerItem)
|
||||
{
|
||||
return Enum.Parse<MainAttributeType>(markerItem, true);
|
||||
}
|
||||
|
||||
public float GetEffectValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
var @enum = Enum.Parse<MainAttributeType>(markerItem, true);
|
||||
return unit.statusManager.GetStatuses()
|
||||
.SelectMany(status => status.effects)
|
||||
.FilterCast<PointChangeMainAttributeEffect>()
|
||||
.Where(effect => effect.mainAttributeType == @enum)
|
||||
.Select(effect => effect.pointModificator)
|
||||
.Sum();
|
||||
}
|
||||
|
||||
public float GetBaseValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
return unit.unitData.baseMainAttributes.Get(Enum.Parse<MainAttributeType>(markerItem, true));
|
||||
}
|
||||
|
||||
public float GetValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
return unit.unitData.mainAttributes.Get(Enum.Parse<MainAttributeType>(markerItem, true));
|
||||
}
|
||||
|
||||
public void UpdateWithValue(UnitObject unit, string markerItem, float formulaValue)
|
||||
{
|
||||
var @enum = Enum.Parse<MainAttributeType>(markerItem, true);
|
||||
var baseValue = GetBaseValue(unit, markerItem);
|
||||
var effectValue = GetEffectValue(unit, markerItem);
|
||||
var previousValue = GetValue(unit, markerItem);
|
||||
var newValue = baseValue + effectValue + formulaValue;
|
||||
var diffValue = newValue - previousValue;
|
||||
unit.unitData.mainAttributes.Set(@enum, (int)newValue);
|
||||
|
||||
unit.unitEvents.onMainAttributeChange.Invoke(
|
||||
new MainAttributeChangeEvent
|
||||
{
|
||||
unit = unit,
|
||||
type = @enum,
|
||||
changedValue = (int)diffValue,
|
||||
newValue = (int)newValue,
|
||||
oldValue = (int)previousValue
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aedbb192285347d585225188cdb9b0e8
|
||||
timeCreated: 1698424887
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.Utilities;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Status.Effect;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.DataCalculator
|
||||
{
|
||||
public class SubAttributeCalcGroup : ICalcGroup
|
||||
{
|
||||
public string GetMarkerGroup()
|
||||
{
|
||||
return "SubAttribute";
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetMarkerItems()
|
||||
{
|
||||
return GetEnums().Select(@enum => @enum.ToString());
|
||||
}
|
||||
|
||||
public Type GetEnumType()
|
||||
{
|
||||
return typeof(SubAttributeType);
|
||||
}
|
||||
|
||||
public IEnumerable<Enum> GetEnums()
|
||||
{
|
||||
return Enum.GetValues(GetEnumType()).OfType<Enum>();
|
||||
}
|
||||
|
||||
public Enum GetEnum(string markerItem)
|
||||
{
|
||||
return Enum.Parse<SubAttributeType>(markerItem, true);
|
||||
}
|
||||
|
||||
public float GetEffectValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
var @enum = Enum.Parse<SubAttributeType>(markerItem, true);
|
||||
return unit.statusManager.GetStatuses()
|
||||
.SelectMany(status => status.effects)
|
||||
.FilterCast<PointChangeSubAttributeEffect>()
|
||||
.Where(effect => effect.subAttributeType == @enum)
|
||||
.Select(effect => effect.pointModificator)
|
||||
.Sum();
|
||||
}
|
||||
|
||||
public float GetBaseValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
return unit.unitData.baseSubAttributes.Get(Enum.Parse<SubAttributeType>(markerItem, true));
|
||||
}
|
||||
|
||||
public float GetValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
return unit.unitData.subAttributes.Get(Enum.Parse<SubAttributeType>(markerItem, true));
|
||||
}
|
||||
|
||||
public void UpdateWithValue(UnitObject unit, string markerItem, float formulaValue)
|
||||
{
|
||||
var @enum = Enum.Parse<SubAttributeType>(markerItem, true);
|
||||
var baseValue = GetBaseValue(unit, markerItem);
|
||||
var effectValue = GetEffectValue(unit, markerItem);
|
||||
var previousValue = GetValue(unit, markerItem);
|
||||
var newValue = baseValue + effectValue + formulaValue;
|
||||
var diffValue = newValue - previousValue;
|
||||
unit.unitData.subAttributes.Set(@enum, newValue);
|
||||
|
||||
unit.unitEvents.onSubAttributeChange.Invoke(
|
||||
new SubAttributeChangeEvent
|
||||
{
|
||||
unit = unit,
|
||||
type = @enum,
|
||||
changedValue = diffValue,
|
||||
newValue = newValue,
|
||||
oldValue = previousValue
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43bd4dac8bba4adda9b5d264fdf10e6e
|
||||
timeCreated: 1698434043
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.Utilities;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.Generic.Status.Effect;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.DataCalculator
|
||||
{
|
||||
public class UnitResourceCalcGroup : ICalcGroup
|
||||
{
|
||||
public string GetMarkerGroup()
|
||||
{
|
||||
return "UnitResource";
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetMarkerItems()
|
||||
{
|
||||
return GetEnums().Select(@enum => @enum.ToString());
|
||||
}
|
||||
|
||||
public Type GetEnumType()
|
||||
{
|
||||
return typeof(UnitResourceType);
|
||||
}
|
||||
|
||||
public IEnumerable<Enum> GetEnums()
|
||||
{
|
||||
return Enum.GetValues(GetEnumType()).OfType<Enum>();
|
||||
}
|
||||
|
||||
public Enum GetEnum(string markerItem)
|
||||
{
|
||||
return Enum.Parse<UnitResourceType>(markerItem);
|
||||
}
|
||||
|
||||
public float GetEffectValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
var @enum = Enum.Parse<UnitResourceType>(markerItem, true);
|
||||
return unit.statusManager.GetStatuses()
|
||||
.SelectMany(status => status.effects)
|
||||
.FilterCast<PointChangeUnitResourceEffect>()
|
||||
.Where(effect => effect.unitResourceType == @enum)
|
||||
.Select(effect => effect.pointModificator)
|
||||
.Sum();
|
||||
}
|
||||
|
||||
public float GetBaseValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
return unit.unitData.baseMaxResources.Get(Enum.Parse<UnitResourceType>(markerItem, true));
|
||||
}
|
||||
|
||||
public float GetValue(UnitObject unit, string markerItem)
|
||||
{
|
||||
return unit.unitData.baseMaxResources.Get(Enum.Parse<UnitResourceType>(markerItem, true));
|
||||
}
|
||||
|
||||
public void UpdateWithValue(UnitObject unit, string markerItem, float formulaValue)
|
||||
{
|
||||
var @enum = Enum.Parse<UnitResourceType>(markerItem, true);
|
||||
var baseValue = GetBaseValue(unit, markerItem);
|
||||
var effectValue = GetEffectValue(unit, markerItem);
|
||||
var previousValue = GetValue(unit, markerItem);
|
||||
var newValue = baseValue + effectValue + formulaValue;
|
||||
var diffValue = newValue - previousValue;
|
||||
unit.unitData.maxResources.Set(@enum, newValue);
|
||||
|
||||
unit.unitEvents.onMaxResourceChange.Invoke(
|
||||
new UnitResourceChangeEvent()
|
||||
{
|
||||
unit = unit,
|
||||
type = @enum,
|
||||
changedValue = diffValue,
|
||||
newValue = newValue,
|
||||
oldValue = previousValue
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 936b8fbe25c9456fb1982c4224628439
|
||||
timeCreated: 1698435779
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e66c83b65a6a4d5f8bb6b11fc5a2a875
|
||||
timeCreated: 1694102043
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Objects.Wearable;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Equipment
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper for equipped item in this slot.
|
||||
/// Its main purpose is to give whole wrapper so other functions can change its wearable.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class EquippedItem
|
||||
{
|
||||
public GameObject gameObject => wearable.gameObject;
|
||||
[field: SerializeField, HideLabel] public WearableObject wearable { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 130f7cd1bd374250b6ddbff5b08b88b7
|
||||
timeCreated: 1694103020
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a225e46f430446449fad4fb3ca3d6586
|
||||
timeCreated: 1666901808
|
||||
@@ -0,0 +1,11 @@
|
||||
using VOID.Generic.Objects.Abstract.Events;
|
||||
using VOID.ScriptableObjects.Abilities;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Events
|
||||
{
|
||||
public class AbilityBookAbilityAddedEvent : AbstractEvent
|
||||
{
|
||||
public UnitObject unit;
|
||||
public BasicAbility abilityAdded;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b28736e9e9e648edb9ccfe4f9ee19108
|
||||
timeCreated: 1688901872
|
||||
@@ -0,0 +1,11 @@
|
||||
using VOID.Generic.Objects.Abstract.Events;
|
||||
using VOID.ScriptableObjects.Abilities;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Events
|
||||
{
|
||||
public class AbilityBookAbilityRemovedEvent : AbstractEvent
|
||||
{
|
||||
public UnitObject unit;
|
||||
public BasicAbility abilityRemoved;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e4599a6c36841aa98e372ed26eb1d65
|
||||
timeCreated: 1688901938
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using VOID.Generic.Objects.Abstract.Events;
|
||||
using VOID.ScriptableObjects.Abilities;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Events
|
||||
{
|
||||
public class AbilityBookAttackAbilityChangeEvent : AbstractEvent
|
||||
{
|
||||
public UnitObject unit;
|
||||
public BasicAttackAbility newAttackAbility;
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6710e6d77a664793a7c40deb20b95221
|
||||
timeCreated: 1688901690
|
||||
@@ -0,0 +1,13 @@
|
||||
using VOID.Generic.Objects.Abstract.Events;
|
||||
using VOID.ScriptableObjects.Abilities;
|
||||
|
||||
namespace VOID.Generic.Objects.Unit.Events
|
||||
{
|
||||
public class AbilityCastEvent : AbstractEvent
|
||||
{
|
||||
public bool prevented = false;
|
||||
|
||||
public UnitObject caster;
|
||||
public BasicAbility ability;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 737380076c5d4133909c25817c912fcf
|
||||
timeCreated: 1687457091
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user