init
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6b3dbb12788f7340bb9988e2f02bbfa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7fb9ff936df4438aa83ac688152290f
|
||||
timeCreated: 1688850173
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict.Ability;
|
||||
using VOID.Generic.DynamicValue;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
using VOID.Generic.Projectile;
|
||||
using VOID.Generic.Requirement;
|
||||
using VOID.Generic.Status.Effect;
|
||||
using VOID.ScriptableObjects.Animations;
|
||||
|
||||
namespace VOID.ScriptableObjects.Abilities
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Zdolności/Ability")]
|
||||
public class BasicAbility : ScriptableObject
|
||||
{
|
||||
[Space(40)]
|
||||
[Title("Display UI")]
|
||||
[Required] public string displayName;
|
||||
[Required] public Texture2D displayIcon;
|
||||
[Required] public AbilityQuality quality;
|
||||
public DynamicText displayDescription;
|
||||
|
||||
[Space(40)]
|
||||
[Title("Resource costs")]
|
||||
public DynamicFormula actionPointCost;
|
||||
public DynamicFormula movePointCost;
|
||||
|
||||
[Space(40)]
|
||||
[Title("Requirements")]
|
||||
[SerializeReference] public List<IUnitRequirement> requirements = new();
|
||||
|
||||
[Space(40)]
|
||||
[Title("Casting")]
|
||||
[Required] public AbilityCastingType castingType;
|
||||
[ShowIf(nameof(ShowAimingType))] [Required] public AbilityAimingType aimingType;
|
||||
[ShowIf(nameof(ShowAimingCorrectionType))] [Required] public AbilityAimingCorrectionType aimingCorrectionType;
|
||||
[InfoBox("Amount of targets for projectiles")]
|
||||
[Required] [MinValue(0)] [ShowIf(nameof(ShowCastUsages))] public int castUsages = 1;
|
||||
|
||||
[Space(40)]
|
||||
[Title("Range")]
|
||||
[ShowIf(nameof(ShowIsRange))] [Required] public bool isRanged;
|
||||
[ShowIf(nameof(ShowRange)), SerializeField] private DynamicFormula _range;
|
||||
public float range => ShowRange() ? _range : 0.25f;
|
||||
|
||||
[Space(40)]
|
||||
[Title("Animation")]
|
||||
[ShowIf(nameof(ShowAbilityAnimationList))] [Required] public ActionAnimationList abilityAnimationList;
|
||||
[ShowIf(nameof(ShowAbilityLoopAnimationList))] [Required] public ActionLoopAnimationList abilityLoopAnimationList;
|
||||
[ShowIf(nameof(ShowCastingAnimationList))] public ActionLoopAnimationList castingAnimationList;
|
||||
|
||||
[Space(40)]
|
||||
[Title("Effects")]
|
||||
public AbilityExecutionMoment applyOnCasterMoment;
|
||||
[SerializeReference] [ShowIf(nameof(ShowApplyOnCaster))] [TypeSelectorSettings(ShowCategories = true, ShowNoneItem = false)]
|
||||
public List<BasicEffect> applyOnCaster = new();
|
||||
[SerializeReference] [ShowIf(nameof(ShowApplyOnTarget))] [TypeSelectorSettings(ShowCategories = true, ShowNoneItem = false)]
|
||||
public List<BasicEffect> applyOnTarget = new();
|
||||
|
||||
[Space(40)]
|
||||
[Title("Tagging")]
|
||||
public AbilityPurposeFlag abilityPurpose;
|
||||
|
||||
[Space(40)]
|
||||
[Title("Projectile")]
|
||||
[InfoBox("IMPORTANT!\nSo far only first step of projectile is fully supported!")]
|
||||
[ShowIf(nameof(ShowProjectileSteps))] [RequiredListLength(1)] public ProjectileStep[] projectileSteps;
|
||||
[InfoBox("If no projectile selected then default empty one will be used!")]
|
||||
[ShowIf(nameof(ShowProjectile))] public ProjectileObject projectile;
|
||||
|
||||
public void OnAddedToUnit(UnitObject unitObject)
|
||||
{
|
||||
displayDescription.AddSource(unitObject);
|
||||
actionPointCost.AddSource(unitObject);
|
||||
movePointCost.AddSource(unitObject);
|
||||
_range.AddSource(unitObject);
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
// If properties are hiden then set them to default values
|
||||
if (!ShowAimingType()) aimingType = AbilityAimingType.Blank;
|
||||
if (!ShowAimingCorrectionType()) aimingCorrectionType = AbilityAimingCorrectionType.None;
|
||||
if (aimingType is AbilityAimingType.Blank) castUsages = 0;
|
||||
if (aimingType is AbilityAimingType.Self) castUsages = 1;
|
||||
if (!ShowIsRange()) isRanged = false;
|
||||
// if (!ShowRange()) range = 0.25f;
|
||||
if (!ShowCastingAnimationList()) castingAnimationList = null;
|
||||
if (!ShowAbilityAnimationList()) abilityAnimationList = null;
|
||||
if (!ShowAbilityLoopAnimationList()) abilityLoopAnimationList = null;
|
||||
if (!ShowApplyOnCaster()) applyOnCaster = new List<BasicEffect>();
|
||||
if (!ShowApplyOnTarget()) applyOnTarget = new List<BasicEffect>();
|
||||
if (!ShowProjectileSteps()) projectileSteps = Array.Empty<ProjectileStep>();
|
||||
if (!ShowProjectile()) projectile = null;
|
||||
}
|
||||
|
||||
private bool ShowAimingType() => castingType is not AbilityCastingType.Instant and not AbilityCastingType.InstantCasting;
|
||||
private bool ShowAimingCorrectionType() => aimingType is AbilityAimingType.Target;
|
||||
private bool ShowCastUsages() => aimingType is not AbilityAimingType.Blank and not AbilityAimingType.Self;
|
||||
private bool ShowIsRange() => castUsages > 0;
|
||||
private bool ShowRange() => ShowIsRange() && isRanged;
|
||||
private bool ShowCastingAnimationList() => castingType is not AbilityCastingType.Instant and not AbilityCastingType.InstantCasting;
|
||||
private bool ShowAbilityAnimationList() => castingType is not AbilityCastingType.Instant and not AbilityCastingType.Channel;
|
||||
private bool ShowAbilityLoopAnimationList() => castingType is AbilityCastingType.Channel;
|
||||
private bool ShowApplyOnCaster() => applyOnCasterMoment is not AbilityExecutionMoment.None;
|
||||
private bool ShowApplyOnTarget() => castUsages > 0;
|
||||
private bool ShowProjectileSteps() => castUsages > 0;
|
||||
private bool ShowProjectile() => castUsages > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0f6b1001ac0404491e4335e421a10de
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- displayIcon: {fileID: 2800000, guid: 3b79c7c79529ea14eb292ec143a074db, type: 3}
|
||||
- quality: {instanceID: 0}
|
||||
- castingAnimationList: {instanceID: 0}
|
||||
- abilityAnimationList: {instanceID: 0}
|
||||
- projectileGameObject: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 3b79c7c79529ea14eb292ec143a074db, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace VOID.ScriptableObjects.Abilities
|
||||
{
|
||||
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Zdolności/Basic Attack")]
|
||||
public class BasicAttackAbility : BasicAbility
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a4840ce9eb24e60a6eaa68626149d9c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- displayIcon: {fileID: 2800000, guid: 00e2f569bbd7dcb4fa841097d986f4dd, type: 3}
|
||||
- quality: {instanceID: 0}
|
||||
- castingAnimationList: {instanceID: 0}
|
||||
- abilityAnimationList: {instanceID: 0}
|
||||
- projectileGameObject: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 00e2f569bbd7dcb4fa841097d986f4dd, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VOID.ScriptableObjects
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Zdolności/AbilityQuality")]
|
||||
public class AbilityQuality : ScriptableObject
|
||||
{
|
||||
[Required, MinValue(0)] public int index;
|
||||
[Required] public string displayName;
|
||||
[Required] public Color color;
|
||||
[Required] public Texture2D background;
|
||||
[Required] public Texture2D border;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26acec6db609464e9fca8cdd6145c60e
|
||||
timeCreated: 1692558957
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23727c3ed6e944dcb8267d3075feafe4
|
||||
timeCreated: 1708427707
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict;
|
||||
|
||||
namespace VOID.ScriptableObjects.Affiliation
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Frakcje/Frakcja")]
|
||||
public class Faction : SerializedScriptableObject
|
||||
{
|
||||
[Required]
|
||||
public string factionName;
|
||||
|
||||
public bool isPlayerFaction;
|
||||
|
||||
public Dictionary<Faction, AttitudeType> factionAttitudes = new();
|
||||
|
||||
public AttitudeType? GetAttitudeFor(Faction otherFaction)
|
||||
{
|
||||
var hasAttitude = factionAttitudes.TryGetValue(otherFaction, out var attitude);
|
||||
return hasAttitude ? attitude : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19982034152d49888067979eab229d10
|
||||
timeCreated: 1708427726
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73da5e8404464bc196bee52cfec32892
|
||||
timeCreated: 1677177162
|
||||
@@ -0,0 +1,12 @@
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Objects.Unit.Animations;
|
||||
|
||||
namespace VOID.ScriptableObjects.Animations
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/ANIMACJE/Animacja akcji")]
|
||||
public class ActionAnimationList : ScriptableObject
|
||||
{
|
||||
[HideLabel] public ActionAnimation list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0930b7dc750246089231144d62850832
|
||||
timeCreated: 1677177419
|
||||
@@ -0,0 +1,12 @@
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Objects.Unit.Animations;
|
||||
|
||||
namespace VOID.ScriptableObjects.Animations
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/ANIMACJE/Animacja zapętlonej akcji")]
|
||||
public class ActionLoopAnimationList : ScriptableObject
|
||||
{
|
||||
[HideLabel] public ActionLoopAnimation list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9efb0f1ac0994983a60614b16cf6c850
|
||||
timeCreated: 1739305139
|
||||
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
using VOID.Generic.Objects.Abstract.Events;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
using VOID.Generic.Status.Effect;
|
||||
|
||||
namespace VOID.ScriptableObjects
|
||||
{
|
||||
[Serializable]
|
||||
[CreateAssetMenu(fileName = "Status", menuName = "GAME DATA/Status", order = 0)]
|
||||
public class BasicStatus : ScriptableObject
|
||||
{
|
||||
[Title("Nested into:")]
|
||||
[ShowInInspector] public AbstractObject forObject { get; private set; }
|
||||
|
||||
[Title("Display")]
|
||||
[Required] public string displayName;
|
||||
[Required] public bool hidden = false;
|
||||
[Required] public Texture2D displayIcon;
|
||||
[Required, TextArea(10,10)] public string description;
|
||||
|
||||
[Title("Effects list")]
|
||||
[Required, SerializeReference] public List<BasicEffect> effects = new();
|
||||
|
||||
[Title("Statuses interactions")]
|
||||
public List<BasicStatus> removes = new();
|
||||
|
||||
[Title("Duration")]
|
||||
public bool permanent = false;
|
||||
[MinValue(0)] public int durationInTurns;
|
||||
[ReadOnly] public int durationLeftInTurns;
|
||||
[ReadOnly] public float durationLeft;
|
||||
|
||||
public event Action OnTimeDecrease;
|
||||
|
||||
public void Init(AbstractObject forObject, UnitObject source = null)
|
||||
{
|
||||
this.forObject = forObject;
|
||||
effects.ForEach(effect => effect.Init(forObject, this, source));
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
if (permanent) durationInTurns = 1;
|
||||
|
||||
// TODO: zdefiniować gdzieś ile czasu w sekundach to tura, na sztywno tutaj dodane 4 sekundy
|
||||
durationLeftInTurns = durationInTurns;
|
||||
durationLeft = durationInTurns*4f - 0.0001f;
|
||||
|
||||
var otherStatuses = forObject.statusManager.GetStatuses();
|
||||
var selfRemove = false;
|
||||
|
||||
foreach (var otherStatus in otherStatuses)
|
||||
{
|
||||
if (otherStatus == this) continue;
|
||||
|
||||
// if other status removes current one
|
||||
selfRemove = selfRemove || otherStatus.removes.Any(removeStatus => removeStatus.GetType() == GetType());
|
||||
|
||||
// if other status is removed by current one
|
||||
if (removes.Any(statusToRemove => statusToRemove.GetType() == otherStatus.GetType())) otherStatus.Cancel();
|
||||
}
|
||||
|
||||
if (selfRemove)
|
||||
{
|
||||
forObject.statusManager.RemoveStatus(this);
|
||||
return;
|
||||
}
|
||||
|
||||
forObject.basicEvents.onStatusStart.Invoke(new StatusEvent
|
||||
{
|
||||
obj = forObject,
|
||||
status = this
|
||||
});
|
||||
|
||||
// Statuses already added via editor inspector need to be started this way
|
||||
foreach (var effect in effects)
|
||||
{
|
||||
effect.OnApply();
|
||||
forObject.basicEvents.onEffectStart.Invoke(new EffectEvent
|
||||
{
|
||||
effect = effect
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void End()
|
||||
{
|
||||
if (permanent)
|
||||
{
|
||||
durationLeftInTurns = 1;
|
||||
// TODO: zdefiniować gdzieś ile czasu w sekundach to tura, na sztywno tutaj dodane 4 sekundy
|
||||
durationLeft += durationInTurns * 4f;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var effect in effects)
|
||||
{
|
||||
effect.OnEnd();
|
||||
forObject.basicEvents.onEffectEnd.Invoke(new EffectEvent
|
||||
{
|
||||
effect = effect
|
||||
});
|
||||
}
|
||||
forObject.statusManager.RemoveStatus(this);
|
||||
forObject.basicEvents.onStatusEnd.Invoke(new StatusEvent
|
||||
{
|
||||
obj = forObject,
|
||||
status = this
|
||||
});
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
effects.ForEach(effect =>
|
||||
{
|
||||
effect.OnCancel();
|
||||
forObject.basicEvents.onEffectEnd.Invoke(new EffectEvent { effect = effect });
|
||||
});
|
||||
forObject.statusManager.RemoveStatus(this);
|
||||
forObject.basicEvents.onStatusEnd.Invoke(new StatusEvent { obj = forObject, status = this });
|
||||
}
|
||||
|
||||
public void OnTurnSelfStart()
|
||||
{
|
||||
// TODO: zdefiniować gdzieś ile czasu w sekundach to tura, na sztywno tutaj dodane 4 sekundy
|
||||
durationLeftInTurns -= 1;
|
||||
durationLeft -= 4f;
|
||||
effects.ForEach(effect => effect.OnTurnSelfStart());
|
||||
OnTimeDecrease?.Invoke();
|
||||
}
|
||||
|
||||
public void OnTurnSelfEnd()
|
||||
{
|
||||
effects.ForEach(effect => effect.OnTurnSelfEnd());
|
||||
if (durationLeft <= 0f) End();
|
||||
}
|
||||
|
||||
public void DecreaseDurationRealTime()
|
||||
{
|
||||
// TODO: zdefiniować gdzieś ile czasu w sekundach to tura, na sztywno tutaj dodane 4 sekundy
|
||||
if (durationLeft%4f - Time.fixedDeltaTime < 0f)
|
||||
{
|
||||
effects.ForEach(effect => effect.OnTurnSelfStart());
|
||||
effects.ForEach(effect => effect.OnTurnSelfEnd());
|
||||
durationLeftInTurns -= 1;
|
||||
}
|
||||
|
||||
OnTimeDecrease?.Invoke();
|
||||
|
||||
durationLeft -= Time.fixedDeltaTime;
|
||||
|
||||
if (durationLeft < 0f) End();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2678cb647fc839c4299e8f7bd5736a62
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- displayIcon: {fileID: 2800000, guid: 09239dcf438fdae40869b80accb1a5ed, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 09239dcf438fdae40869b80accb1a5ed, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3241fb5819147009c589984406cbe22
|
||||
timeCreated: 1717614065
|
||||
@@ -0,0 +1,12 @@
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VOID.ScriptableObjects.DropTable
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/DropTable/DropTable")]
|
||||
public class DropTableScriptableObject : ScriptableObject
|
||||
{
|
||||
[HideLabel]
|
||||
public Generic.DropTable.DropTable value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07dd4d15324c470b9be6c7d393c6d2df
|
||||
timeCreated: 1717772254
|
||||
@@ -0,0 +1,15 @@
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VOID.ScriptableObjects
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Przedmioty/ItemQuality")]
|
||||
public class ItemQuality : ScriptableObject
|
||||
{
|
||||
[Required, MinValue(0)] public int index;
|
||||
[Required] public string displayName;
|
||||
[Required] public Color color;
|
||||
[Required] public Texture2D background;
|
||||
[Required] public Texture2D border;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 33b2db17b9e859949a8025235ec94d33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90116ef6248148bd8d8e48f0c2f69570
|
||||
timeCreated: 1729195208
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Status.Effect;
|
||||
|
||||
namespace VOID.ScriptableObjects.Player
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Player/LevelUpOption")]
|
||||
public class LevelUpOption : ScriptableObject
|
||||
{
|
||||
// GENERIC
|
||||
[Title("Generic")]
|
||||
[Required]
|
||||
public string displayName;
|
||||
|
||||
[Required]
|
||||
[PreviewField]
|
||||
public Texture2D displayIcon;
|
||||
|
||||
[TextArea(10, 10)]
|
||||
public string displayDescription;
|
||||
|
||||
[SerializeReference]
|
||||
[RequiredListLength(MinLength = 1)]
|
||||
public List<BasicEffect> effects = new();
|
||||
|
||||
// CHANCE
|
||||
[Title("Chance")]
|
||||
[MinValue(0)]
|
||||
public float weight = 1f;
|
||||
|
||||
// LIMIT
|
||||
[Title("Limit")]
|
||||
[OnValueChanged(nameof(OnIsLimitedChanged))]
|
||||
public bool isLimited;
|
||||
|
||||
[MinValue(1)]
|
||||
[EnableIf(nameof(isLimited))]
|
||||
public int limit = 9999;
|
||||
|
||||
private void OnIsLimitedChanged() => limit = isLimited ? limit : 9999;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2fb09487a70141259f18e2ecade4b9aa
|
||||
timeCreated: 1729195215
|
||||
@@ -0,0 +1,178 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using InfinityPBR.ModularCharacterHelper;
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.Utilities;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
using VOID.Generic.Util;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace VOID.ScriptableObjects
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Generator/Generator Jednostki")]
|
||||
public class UnitGenerator : ScriptableObject
|
||||
{
|
||||
[Title("Unit References")]
|
||||
[SerializeField] private UnitObject[] _unitPrefabs;
|
||||
[SerializeField] private Material[] _skinMaterials;
|
||||
[SerializeField] private Material[] _hairMaterials;
|
||||
|
||||
[Space(100)]
|
||||
[Title("Model")]
|
||||
[InfoBox("If prefab part can't be attached to unit prefab then it'll be skipped!")]
|
||||
[SerializeField] private bool _generateHair;
|
||||
[SerializeField, ShowIf(nameof(_generateHair)), Required] private ModularPart[] _hairPrefabs;
|
||||
|
||||
[Title("Colors")]
|
||||
[InfoBox("If colors list is empty then randomize new one!")]
|
||||
[SerializeField] private bool _generateSkinColor;
|
||||
[SerializeField, ShowIf(nameof(_generateSkinColor))] private Color[] _skinColors;
|
||||
[SerializeField] private bool _generateHairColor;
|
||||
[SerializeField, ShowIf(nameof(_generateHairColor))] private Color[] _hairColors;
|
||||
|
||||
[Title("Main Attributes")]
|
||||
[SerializeField] private bool _generateMainAttributes;
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _strength = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _dexterity = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _intelligence = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _constitution = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _speed = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _perception = new(4, 7);
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (!_generateHair)
|
||||
{
|
||||
_hairPrefabs = null;
|
||||
}
|
||||
|
||||
if (!_generateSkinColor)
|
||||
{
|
||||
_skinColors = null;
|
||||
}
|
||||
|
||||
if (!_generateHairColor)
|
||||
{
|
||||
_hairColors = null;
|
||||
}
|
||||
|
||||
if (!_generateMainAttributes)
|
||||
{
|
||||
_strength = new Vector2Int(4, 7);
|
||||
_dexterity = new Vector2Int(4, 7);
|
||||
_intelligence = new Vector2Int(4, 7);
|
||||
_constitution = new Vector2Int(4, 7);
|
||||
_speed = new Vector2Int(4, 7);
|
||||
_perception = new Vector2Int(4, 7);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate new <see cref="UnitObject"/>:<br/>
|
||||
/// 1. Selects random <see cref="UnitObject"/> prefab<br/>
|
||||
/// 2. Wait for full initialization of <see cref="UnitObject"/><br/>
|
||||
/// 3. Updates <see cref="UnitObject"/> with random things defined via inspector
|
||||
/// </summary>
|
||||
/// <returns>Instantiated random <see cref="UnitObject"/></returns>
|
||||
public UnitObject Generate(int? seed = null)
|
||||
{
|
||||
if (seed.HasValue) RandomUtil.InitState(seed.Value);
|
||||
var unit = Instantiate(RandomUtil.RandomElement(_unitPrefabs));
|
||||
Randomize(unit);
|
||||
return unit;
|
||||
}
|
||||
|
||||
private void Randomize(UnitObject unit)
|
||||
{
|
||||
RandomizeHair(unit);
|
||||
RandomizeSkinColor(unit);
|
||||
RandomizeHairColor(unit);
|
||||
RandomizeMainAttributes(unit);
|
||||
}
|
||||
|
||||
private void RandomizeHair(UnitObject unit)
|
||||
{
|
||||
if (!_generateHair) return;
|
||||
|
||||
var modularCharacter = unit.unitState.modularCharacter;
|
||||
var validHairPrefabs = _hairPrefabs.Where(hair => hair.avatar == modularCharacter.avatar).ToList();
|
||||
|
||||
if (validHairPrefabs.IsNullOrEmpty()) return;
|
||||
|
||||
modularCharacter.AttachPart(Instantiate(RandomUtil.RandomElement(validHairPrefabs), unit.transform));
|
||||
}
|
||||
|
||||
private void RandomizeSkinColor(UnitObject unit)
|
||||
{
|
||||
if (!_generateSkinColor) return;
|
||||
if (_skinMaterials.IsNullOrEmpty()) return;
|
||||
|
||||
ApplyTintToMaterials(unit, _skinColors, _skinMaterials);
|
||||
}
|
||||
|
||||
private void RandomizeHairColor(UnitObject unit)
|
||||
{
|
||||
if (!_generateHairColor) return;
|
||||
if (_hairMaterials.IsNullOrEmpty()) return;
|
||||
|
||||
ApplyTintToMaterials(unit, _hairColors, _hairMaterials);
|
||||
}
|
||||
|
||||
private void ApplyTintToMaterials(UnitObject unit, Color[] colors, Material[] forMaterials)
|
||||
{
|
||||
// Find renderers with this material to add tint color
|
||||
var foundRenderers = unit.GetComponentsInChildren<Renderer>()
|
||||
.Where(renderer => forMaterials.Any(material => renderer.sharedMaterials.Contains(material)))
|
||||
.ToList();
|
||||
|
||||
if (foundRenderers.IsNullOrEmpty()) return;
|
||||
|
||||
// Get random defined color if present OR randomize new one
|
||||
var color = colors.IsNullOrEmpty()
|
||||
? Random.ColorHSV(0, 1, 0, 1, 0, 1, 0, 1)
|
||||
: RandomUtil.RandomElement(colors);
|
||||
|
||||
// Normally renderers here will use shared materials, but we want to create colored "variants" thats why
|
||||
// we need to instantiate material and add tint color if this is matching material. Other materials will
|
||||
// instantiate too anyway even without our help so lets do all of them by ourselfs!
|
||||
foreach (var foundRenderer in foundRenderers)
|
||||
{
|
||||
var materials = new List<Material>();
|
||||
foreach (var sharedMaterial in foundRenderer.sharedMaterials)
|
||||
{
|
||||
if (forMaterials.Contains(sharedMaterial))
|
||||
{
|
||||
var material = Instantiate(sharedMaterial);
|
||||
material.color = color;
|
||||
materials.Add(material);
|
||||
}
|
||||
else
|
||||
{
|
||||
materials.Add(sharedMaterial);
|
||||
}
|
||||
}
|
||||
foundRenderer.sharedMaterials = materials.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void RandomizeMainAttributes(UnitObject unit)
|
||||
{
|
||||
if (!_generateMainAttributes) return;
|
||||
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Strength,
|
||||
RandomUtil.RandomInteger(_strength.x, _strength.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Dexterity,
|
||||
RandomUtil.RandomInteger(_dexterity.x, _dexterity.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Intelligence,
|
||||
RandomUtil.RandomInteger(_intelligence.x, _intelligence.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Constitution,
|
||||
RandomUtil.RandomInteger(_constitution.x, _constitution.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Speed,
|
||||
RandomUtil.RandomInteger(_speed.x, _speed.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Perception,
|
||||
RandomUtil.RandomInteger(_perception.x, _perception.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f3d6f4089f84b209dcfdec18d77d1ef
|
||||
timeCreated: 1722356559
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0140166f0a34056accc53cafb57e3d6
|
||||
timeCreated: 1706982749
|
||||
@@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace VOID.ScriptableObjects.World
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Świat/AreaConnectionTag")]
|
||||
public class AreaConnectionTag : ScriptableObject
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa05b96b0c6844328f981a6b7573d3af
|
||||
timeCreated: 1706820031
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.World;
|
||||
|
||||
namespace VOID.ScriptableObjects.World
|
||||
{
|
||||
[Serializable]
|
||||
public class WorldAreaGeneratorSettings
|
||||
{
|
||||
[RequiredListLength(MinLength = 1)]
|
||||
public List<ComplexArea> group;
|
||||
|
||||
[HorizontalGroup("generic")]
|
||||
[LabelWidth(125)]
|
||||
public bool useRotatedVariants = true;
|
||||
|
||||
[HorizontalGroup("generic")]
|
||||
[MinValue(0)]
|
||||
[LabelWidth(75)]
|
||||
public float weight = 1f;
|
||||
|
||||
[HorizontalGroup("limit")]
|
||||
[OnValueChanged(nameof(OnIsLimitedChanged))]
|
||||
[LabelWidth(125)]
|
||||
public bool isLimited;
|
||||
|
||||
[HorizontalGroup("limit")]
|
||||
[MinValue(1)]
|
||||
[EnableIf(nameof(isLimited))]
|
||||
[LabelWidth(75)]
|
||||
public int limit = 9999;
|
||||
|
||||
[HorizontalGroup("distance")]
|
||||
[OnValueChanged(nameof(OnRequireDistanceChanged))]
|
||||
[LabelWidth(125)]
|
||||
public bool requireDistance;
|
||||
|
||||
[HorizontalGroup("distance")]
|
||||
[EnableIf(nameof(requireDistance))]
|
||||
[MinMaxSlider(1, 999, true)]
|
||||
[LabelWidth(75)]
|
||||
public Vector2Int distance = new(1, 999);
|
||||
|
||||
private void OnIsLimitedChanged()
|
||||
{
|
||||
if (!isLimited)
|
||||
{
|
||||
limit = 9999;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRequireDistanceChanged()
|
||||
{
|
||||
if (!requireDistance)
|
||||
{
|
||||
distance = new Vector2Int(1, 999);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 476f8224578f47718b465606b21d811d
|
||||
timeCreated: 1707226691
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.World;
|
||||
|
||||
namespace VOID.ScriptableObjects.World
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Świat/WorldGeneratorSettings")]
|
||||
public class WorldGeneratorSettings : ScriptableObject
|
||||
{
|
||||
[InfoBox(nameof(ComplexArea) + " and its variants to select for <b>STARTING</b> area.")]
|
||||
[RequiredListLength(MinLength = 1)]
|
||||
public List<ComplexArea> startingComplexAreas = new();
|
||||
|
||||
[InfoBox(nameof(ComplexArea) + " and its variants to use for generating process.")]
|
||||
[RequiredListLength(MinLength = 1)]
|
||||
public List<WorldAreaGeneratorSettings> list = new();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 604a9f4289d742db95af798270fa9bf2
|
||||
timeCreated: 1706982922
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"reference": "GUID:b06f3eed7b514aa429abd6e0a5557793"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c020c38b3a82bb44ac458dc03ea46e1
|
||||
AssemblyDefinitionReferenceImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user