Compare commits

..

1 Commits

Author SHA1 Message Date
ddd7caad77 possible solution for ability system 2024-08-21 21:48:06 +01:00
118 changed files with 1942 additions and 1953 deletions

View File

@ -6834,7 +6834,6 @@ MonoBehaviour:
- {fileID: 11400000, guid: baa6f2c09656e8148933cf51d6e9d0df, type: 2}
- {fileID: 11400000, guid: 679598ad64000fa4aa4a8b5c1cb568e3, type: 2}
- {fileID: 11400000, guid: 0c191267adf0be840a2ac87dfbcbacc2, type: 2}
- {fileID: 11400000, guid: 3cb8d7161315a384586026a48385b0b1, type: 2}
--- !u!1 &7475116341184709871
GameObject:
m_ObjectHideFlags: 0

View File

@ -1,54 +1,5 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2854504623699103925
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2788171593351923773}
- component: {fileID: 3034607606178470595}
m_Layer: 0
m_Name: NecroAutoCastOnSceneRefresh
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2788171593351923773
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2854504623699103925}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 7484556474031461785}
m_RootOrder: 24
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &3034607606178470595
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2854504623699103925}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dd7e427c67a74ff4b8b8d14b39a134bc, type: 3}
m_Name:
m_EditorClassIdentifier:
possibleAutoSummons:
- {fileID: 11400000, guid: 0db150a6bbd0c1d478dbd3fc09a6ef85, type: 2}
- {fileID: 11400000, guid: 4b21d1ec90616ac4a8f0ff30311a6a1f, type: 2}
- {fileID: 11400000, guid: 6cf7c174663354f4bb94833236e61c18, type: 2}
- {fileID: 11400000, guid: f0272d37cc7635f4cbdfb40b1a16a9e7, type: 2}
--- !u!1001 &2176522877944764073
PrefabInstance:
m_ObjectHideFlags: 0
@ -338,11 +289,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 389de3cac2aa89247bd947ebc2fb91ac, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &7484556474031461785 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 8785094005405139760, guid: 9c432d220280f704684a6d5b9354c782, type: 3}
m_PrefabInstance: {fileID: 2176522877944764073}
m_PrefabAsset: {fileID: 0}
--- !u!114 &7851041350907075303 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 8268627081631403086, guid: 9c432d220280f704684a6d5b9354c782, type: 3}

View File

@ -1,32 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a5d5cf82dd5c07f438f5809f773372e2, type: 3}
m_Name: 0-HumanSlashAbility
m_EditorClassIdentifier:
Icon: {fileID: 21300000, guid: 28a02df1369b7fd4eab040459b0cc450, type: 3}
targettingTags: []
tags: []
abilityEffects: []
castTime: 0.5
manaCost: 0
healthCost: 0
classResourceCost: 0
cooldown: 0
castableWhileMoving: 0
animationType: 2
slashPrefab: {fileID: 0}
regenHealthOnHit: 0
regenManaOnHit: 0
healthOnHit: 0
manaOnHit: 0
lifeSpan: 0
range: 0

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 3cb8d7161315a384586026a48385b0b1
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f861a28adf4fe7b44a7b1f9db0457a91
guid: e3c7acee50b617343adac7c021b18fd4
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -0,0 +1,37 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4aedcd11782e6544e8786936943468a6, type: 3}
m_Name: IceShard_Template
m_EditorClassIdentifier:
abilityName: Ice Shard
description: Hurl an ice shard towards the targeted direction
icon: {fileID: 21300000, guid: 50a820d3228a2bf4da98a6e769e90f12, type: 3}
targettingTags:
- {fileID: 11400000, guid: 3ac5bfbf7e1fbdd4baec1c17bd3d874c, type: 2}
- {fileID: 11400000, guid: 201eca8f8c72ba74dbb0854cad29be4f, type: 2}
tags:
- {fileID: 11400000, guid: 4e6f036fb4aad9b428694360fcc62f88, type: 2}
- {fileID: 11400000, guid: 918ee6f8846e6a9449166ac16b6330ae, type: 2}
abilityEffects:
- {fileID: 11400000, guid: d441f01dcc2dc5943a605b0bbffa1a03, type: 2}
castTime: 0.5
manaCost: 6
healthCost: 0
classResourceCost: 0
cooldown: 0
castableWhileMoving: 0
animationType: 1
projectilePrefab: {fileID: 4298339421658607672, guid: e2e28eac2a915464284517bc9f1425b0, type: 3}
projectileSpeed: 10
lifeSpan: 1.5
canPierce: 0
canHitSelf: 0

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: bfc36a68112b4534c8eb33a78518ab6c
guid: b7745cb695af3bf4cbc59d105bb761ae
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000

View File

@ -1,44 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 03064a0d3f6200145b50c40e4cd12615, type: 3}
m_Name: TestingAwakenings
m_EditorClassIdentifier:
data:
Name:
Description:
CurrentPoints: 0
MaxPoints: 1
requiredAwakenings: []
StrengthBonus: 0
AgilityBonus: 0
IntelligenceBonus: 0
SpiritBonus: 0
VitalityBonus: 0
StrengthPercentBonus: 0
AgilityPercentBonus: 0
IntelligencePercentBonus: 0
SpiritPercentBonus: 0
VitalityPercentBonus: 0
AttackDamageBonus: 0
SpellDamageBonus: 0
CritChanceBonus: 0
CritDamageBonus: 0
MaxHealthBonus: 0
ArmorBonus: 0
MagicResistanceBonus: 0
AttackDamagePercentBonus: 0
SpellDamagePercentBonus: 0
CritChancePercentBonus: 0
CritDamagePercentBonus: 0
MaxHealthPercentBonus: 0
ArmorPercentBonus: 0
MagicResistancePercentBonus: 0

View File

@ -16,7 +16,7 @@ MonoBehaviour:
- {fileID: 11400000, guid: 4e6f036fb4aad9b428694360fcc62f88, type: 2}
influencingStats:
- statTag: {fileID: 11400000, guid: 918ee6f8846e6a9449166ac16b6330ae, type: 2}
percentInfluence: 0.2
percentInfluence: 0.15
baseValue: 2
damageType: 1
AlliedTargetMultiplier: 1

View File

@ -16,7 +16,7 @@ MonoBehaviour:
- {fileID: 11400000, guid: 4e6f036fb4aad9b428694360fcc62f88, type: 2}
influencingStats:
- statTag: {fileID: 11400000, guid: 918ee6f8846e6a9449166ac16b6330ae, type: 2}
percentInfluence: 0.2
percentInfluence: 0.15
baseValue: 1
damageType: 1
AlliedTargetMultiplier: 1

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 307841cd77271a8468c442f4a604e862
guid: 4b5716c4ad6e39c409e2e8217f2fcdec
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9b2dc875bac316e49b4963b666aafd44
guid: d4809e1c0c1448448b74cf90992702b2
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -0,0 +1,19 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
[CreateAssetMenu(fileName = "New Anti-Projectile Ability", menuName = "RiftMayhem/Abilities/Anti-Projectile Ability")]
public class AntiProjectileAbilityTemplate : BaseAbility
{
public GameObject antiProjectilePrefab;
public float duration;
public bool followUser;
public override IAbilityProperties CreateProperties()
{
return new AntiProjectileAbilityProperties();
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 85e3596f5bd1bf44d8343b3f2b4cd7ac
guid: dcd80a6f46ee35e4ca73befb46c40e7d
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
[CreateAssetMenu(fileName = "New AoE Ability", menuName = "RiftMayhem/Abilities/AoE Ability")]
public class AreaOfEffectAbilityTemplate : BaseAbility
{
public GameObject aoePrefab;
public float radius;
public float lifeSpan;
public float telegraphDelay;
public bool spawnUnderUser;
public override IAbilityProperties CreateProperties()
{
return new AreaOfEffectAbilityProperties();
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: ecbc603708f7b784ab0a4bc2cce24156
guid: 4fd10732ea3f0264a82b38345f89bdc4
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,19 @@
using UnityEngine;
namespace Template_RuntimeInstance
{
[CreateAssetMenu(fileName = "New AoE Over Time Ability", menuName = "RiftMayhem/Abilities/AoE Over Time Ability")]
public class AreaOfEffectOverTimeAbilityTemplate : AreaOfEffectAbilityTemplate
{
[Header("Over Time Settings")]
public float duration;
public bool followUser;
public bool followTarget;
public bool damageFollowingTarget;
public override IAbilityProperties CreateProperties()
{
return new AreaOfEffectOverTimeAbilityProperties();
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 03064a0d3f6200145b50c40e4cd12615
guid: 09d6928bbd92a3c4890a0be6e545de0e
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e0c2df9140a6fce45a9576a1db3e0d43
guid: 6519cff19268c1d42ac22ac8367fafbd
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -0,0 +1,62 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public abstract class BaseAbility : ScriptableObject
{
public string abilityName;
public string description;
public Sprite icon;
public List<TargetTag> targettingTags = new List<TargetTag>();
public List<GameTag> tags = new List<GameTag>();
public List<BaseEffect> abilityEffects = new List<BaseEffect>();
public float castTime;
public float manaCost;
public float healthCost = 0;
public float classResourceCost = 0;
public float cooldown;
public bool castableWhileMoving;
public AbilityAnimationType animationType;
public abstract IAbilityProperties CreateProperties();
private void OnValidate()
{
InitializeUniqueTags();
}
private void OnEnable()
{
InitializeUniqueTags();
}
public void InitializeUniqueTags()
{
tags.Clear();
// Iterate through each effect and add unique GameTags to uniqueTags list
foreach (var effect in abilityEffects)
{
if (effect != null)
{
foreach (var tag in effect.tags)
{
if (!tags.Contains(tag))
{
tags.Add(tag);
}
}
foreach (var influencingStat in effect.influencingStats)
{
if (!tags.Contains(influencingStat.statTag))
{
tags.Add(influencingStat.statTag);
}
}
}
}
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 12323d49914f700448c37231a033bb2c
guid: ec6e4aa3effacb4468d53cb718f1c98a
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
[CreateAssetMenu(fileName = "New Channeled Ability", menuName = "RiftMayhem/Abilities/Channeled Ability")]
public class ChanneledAbilityTemplate : BaseAbility
{
public GameObject prefab;
public float duration;
public float radius;
public bool canHitSelf;
public bool followUser;
public override IAbilityProperties CreateProperties()
{
return new ChanneledAbilityProperties();
}
}
}

View File

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

View File

@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
[CreateAssetMenu(fileName = "New Potion Ability", menuName = "RiftMayhem/Abilities/Potion Ability")]
public class PotionAbilityTemplate : BaseAbility
{
public float healingPercent;
public override IAbilityProperties CreateProperties()
{
return new PotionAbilityProperties();
}
}
}

View File

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

View File

@ -0,0 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
[CreateAssetMenu(fileName = "New Projectile Ability", menuName = "RiftMayhem/Abilities/Projectile Ability")]
public class ProjectileAbilityTemplate : BaseAbility
{
public GameObject projectilePrefab;
public float projectileSpeed;
public float lifeSpan;
public bool canPierce;
public bool canHitSelf;
public override IAbilityProperties CreateProperties()
{
return new ProjectileAbilityProperties();
}
}
}

View File

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

View File

@ -0,0 +1,23 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
[CreateAssetMenu(fileName = "New Slash Ability", menuName = "RiftMayhem/Abilities/Slash Ability")]
public class SlashAbilityTemplate : BaseAbility
{
public GameObject slashPrefab;
public float range;
public bool regenHealthOnHit;
public bool regenManaOnHit;
public float healthOnHit;
public float manaOnHit;
public override IAbilityProperties CreateProperties()
{
return new SlashAbilityProperties();
}
}
}

View File

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

View File

@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
[CreateAssetMenu(fileName = "New Summon Ability", menuName = "RiftMayhem/Abilities/Summon Ability")]
public class SummonAbilityTemplate : BaseAbility
{
public GameObject minionPrefab;
public override IAbilityProperties CreateProperties()
{
return new SummonAbilityProperties();
}
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cbcbf086a3625ed4b92cad3caffbd9b2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,82 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class AbilityInstance
{
public string id;
public BaseAbility template;
public float currentCooldown;
public float currentManaCost;
public float currentHealthCost;
public float currentClassResourceCost;
public List<BaseEffect> currentEffects;
public List<IAbilityModifier> currentModifiers;
public IAbilityProperties properties;
public AbilityInstance(BaseAbility template)
{
this.id = System.Guid.NewGuid().ToString();
this.template = template;
this.currentCooldown = template.cooldown;
this.currentManaCost = template.manaCost;
this.currentHealthCost = template.healthCost;
this.currentClassResourceCost = template.classResourceCost;
this.currentEffects = new List<BaseEffect>(template.abilityEffects);
this.currentModifiers = new List<IAbilityModifier>();
this.properties = template.CreateProperties();
this.properties.Initialize(template);
}
public void AddModifier(IAbilityModifier abilityModifier)
{
currentModifiers.Add(abilityModifier);
}
public void RemoveModifier(IAbilityModifier abilityModifier)
{
currentModifiers.Remove(abilityModifier);
}
public void Execute(PhotonView user, Taggable userTag, Vector3 targetPosition, Taggable targetTag)
{
AbilityExecutionContext context = new AbilityExecutionContext
{
User = user,
UserTag = userTag,
TargetPosition = targetPosition,
TargetTag = targetTag,
Cooldown = currentCooldown,
ManaCost = currentManaCost,
HealthCost = currentHealthCost,
ClassResourceCost = currentClassResourceCost,
Effects = currentEffects,
Modifiers = currentModifiers
};
SpendResourcesNecessary(user);
properties.ModifiedExecution(context);
/*foreach (var effect in context.Effects)
{
effect.ApplyEffect(context.UserTag, new List<Taggable> { context.TargetTag });
}
currentCooldown = context.Cooldown;
currentManaCost = context.ManaCost;
currentHealthCost = context.HealthCost;
currentClassResourceCost = context.ClassResourceCost;*/
}
public void SpendResourcesNecessary(PhotonView user)
{
user.GetComponent<Mana>().ChangeValue(-currentManaCost);
user.GetComponent<Health>().ChangeValue(-currentHealthCost);
user.GetComponent<ClassResource>()?.ChangeValue(-currentClassResourceCost);
}
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b45f42084a741f044ac75c6489a6c53e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,37 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class AntiProjectileAbilityProperties : IAbilityProperties
{
public float duration;
public bool followUser;
private GameObject antiProjectilePrefab;
public void Initialize(BaseAbility template)
{
if (template is AntiProjectileAbilityTemplate antiProjectileTemplate)
{
duration = antiProjectileTemplate.duration;
followUser = antiProjectileTemplate.followUser;
antiProjectilePrefab = antiProjectileTemplate.antiProjectilePrefab;
}
}
public void ModifiedExecution(AbilityExecutionContext context)
{
GameObject antiProjectileGO = PhotonNetwork.Instantiate("Abilities/" + antiProjectilePrefab.name, context.User.transform.position, context.User.transform.rotation);
NetworkedAntiProjectile networkedAntiProjectile = antiProjectileGO.GetComponent<NetworkedAntiProjectile>();
if (networkedAntiProjectile != null)
{
networkedAntiProjectile.Initialize(context, this);
}
}
public float GetLifeSpan() => duration;
public bool GetCanHitSelf() => false;
}
}

View File

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

View File

@ -0,0 +1,49 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class AreaOfEffectAbilityProperties : IAbilityProperties
{
public float radius;
public float lifeSpan;
public float telegraphDelay;
public bool canHitSelf;
public bool spawnUnderUser;
private GameObject aoePrefab;
public bool GetCanHitSelf()
{
return canHitSelf;
}
public float GetLifeSpan()
{
return lifeSpan;
}
public virtual void Initialize(BaseAbility template)
{
if (template is AreaOfEffectAbilityTemplate aoeTemplate)
{
radius = aoeTemplate.radius;
lifeSpan = aoeTemplate.lifeSpan;
spawnUnderUser = aoeTemplate.spawnUnderUser;
aoePrefab = aoeTemplate.aoePrefab;
telegraphDelay = aoeTemplate.telegraphDelay;
}
}
public virtual void ModifiedExecution(AbilityExecutionContext context)
{
GameObject aoeGO = PhotonNetwork.Instantiate("Abilities/" + aoePrefab.name, context.TargetPosition, Quaternion.identity);
NetworkedAreaOfEffect networkedAOE = aoeGO.GetComponent<NetworkedAreaOfEffect>();
if (networkedAOE != null)
{
networkedAOE.Initialize(context, this);
}
}
}
}

View File

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

View File

@ -0,0 +1,39 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class AreaOfEffectOverTimeAbilityProperties : AreaOfEffectAbilityProperties
{
public float duration;
public bool followUser;
public bool followTarget;
public bool damageFollowingTarget;
private GameObject prefab;
public override void Initialize(BaseAbility template)
{
base.Initialize(template);
if (template is AreaOfEffectOverTimeAbilityTemplate aoeotTemplate)
{
duration = aoeotTemplate.duration;
followUser = aoeotTemplate.followUser;
followTarget = aoeotTemplate.followTarget;
damageFollowingTarget = aoeotTemplate.damageFollowingTarget;
prefab = aoeotTemplate.aoePrefab;
}
}
public override void ModifiedExecution(AbilityExecutionContext context)
{
GameObject aoeGO = PhotonNetwork.Instantiate("Abilities/" + prefab.name, context.TargetPosition, Quaternion.identity);
NetworkedAreaOfEffectOverTime networkedAOEOT = aoeGO.GetComponent<NetworkedAreaOfEffectOverTime>();
if (networkedAOEOT != null)
{
networkedAOEOT.Initialize(context, this);
}
}
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a69d40a56dc8f7d49989c92a78617dd1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public interface IAbilityProperties
{
void Initialize(BaseAbility template);
void ModifiedExecution(AbilityExecutionContext context);
float GetLifeSpan();
bool GetCanHitSelf();
}
}

View File

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

View File

@ -0,0 +1,41 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class ChanneledAbilityProperties : IAbilityProperties
{
public float duration;
public float radius;
public bool canHitSelf;
public bool followUser;
private GameObject prefab;
public void Initialize(BaseAbility template)
{
if (template is ChanneledAbilityTemplate channeledTemplate)
{
duration = channeledTemplate.duration;
radius = channeledTemplate.radius;
canHitSelf = channeledTemplate.canHitSelf;
followUser = channeledTemplate.followUser;
prefab = channeledTemplate.prefab;
}
}
public void ModifiedExecution(AbilityExecutionContext context)
{
GameObject channeledGO = PhotonNetwork.Instantiate("Abilities/" + prefab.name, context.User.transform.position, context.User.transform.rotation);
NetworkedChanneling networkedChanneling = channeledGO.GetComponent<NetworkedChanneling>();
if (networkedChanneling != null)
{
networkedChanneling.Initialize(context, this);
}
}
public float GetLifeSpan() => duration;
public bool GetCanHitSelf() => canHitSelf;
}
}

View File

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

View File

@ -0,0 +1,32 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class PotionAbilityProperties : IAbilityProperties
{
public float healingPercent;
public void Initialize(BaseAbility template)
{
if (template is PotionAbilityTemplate potionTemplate)
{
healingPercent = potionTemplate.healingPercent;
}
}
public void ModifiedExecution(AbilityExecutionContext context)
{
Health userHealth = context.User.GetComponent<Health>();
if (userHealth != null)
{
float healAmount = userHealth.GetMaxValue() * healingPercent;
userHealth.ChangeValue(healAmount);
}
}
public float GetLifeSpan() => 0f; // Potions typically have instant effect
public bool GetCanHitSelf() => true;
}
}

View File

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

View File

@ -0,0 +1,48 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class ProjectileAbilityProperties : IAbilityProperties
{
public float projectileSpeed;
public float lifeSpan;
public bool canPierce;
public bool canHitSelf;
private GameObject projectilePrefab;
public bool GetCanHitSelf()
{
return canHitSelf;
}
public float GetLifeSpan()
{
return lifeSpan;
}
public void Initialize(BaseAbility template)
{
if (template is ProjectileAbilityTemplate projectileTemplate)
{
projectileSpeed = projectileTemplate.projectileSpeed;
lifeSpan = projectileTemplate.lifeSpan;
canPierce = projectileTemplate.canPierce;
canHitSelf = projectileTemplate.canHitSelf;
projectilePrefab = projectileTemplate.projectilePrefab;
}
}
public void ModifiedExecution(AbilityExecutionContext context)
{
GameObject projectileGO = PhotonNetwork.Instantiate("Abilities/" + projectilePrefab.name, context.User.GetComponentInChildren<ProjectileSpawnLocationController>().transform.position, context.User.GetComponentInChildren<ProjectileSpawnLocationController>().transform.rotation);
NetworkedProjectile networkedProjectile = projectileGO.GetComponent<NetworkedProjectile>();
if (networkedProjectile != null)
{
networkedProjectile.Initialize(context, this);
}
}
}
}

View File

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

View File

@ -0,0 +1,43 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class SlashAbilityProperties : IAbilityProperties
{
public float range;
public bool regenHealthOnHit;
public bool regenManaOnHit;
public float healthOnHit;
public float manaOnHit;
private GameObject slashPrefab;
public void Initialize(BaseAbility template)
{
if (template is SlashAbilityTemplate slashTemplate)
{
range = slashTemplate.range;
regenHealthOnHit = slashTemplate.regenHealthOnHit;
regenManaOnHit = slashTemplate.regenManaOnHit;
healthOnHit = slashTemplate.healthOnHit;
manaOnHit = slashTemplate.manaOnHit;
slashPrefab = slashTemplate.slashPrefab;
}
}
public void ModifiedExecution(AbilityExecutionContext context)
{
GameObject slashGO = PhotonNetwork.Instantiate("Abilities/" + slashPrefab.name, context.User.transform.position, context.User.transform.rotation);
NetworkedSlash networkedSlash = slashGO.GetComponent<NetworkedSlash>();
if (networkedSlash != null)
{
networkedSlash.Initialize(context, this);
}
}
public float GetLifeSpan() => 0.5f; // Adjust this value as needed
public bool GetCanHitSelf() => false;
}
}

View File

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

View File

@ -0,0 +1,33 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class SummonAbilityProperties : IAbilityProperties
{
private GameObject minionPrefab;
public void Initialize(BaseAbility template)
{
if (template is SummonAbilityTemplate summonTemplate)
{
minionPrefab = summonTemplate.minionPrefab;
}
}
public void ModifiedExecution(AbilityExecutionContext context)
{
GameObject minionGO = PhotonNetwork.Instantiate("Abilities/" + minionPrefab.name, context.User.transform.position, context.User.transform.rotation);
NetworkedSummonedMinion networkedMinion = minionGO.GetComponent<NetworkedSummonedMinion>();
if (networkedMinion != null)
{
networkedMinion.Initialize(context, this);
}
}
public float GetLifeSpan() => 0f; // Summons typically don't have a lifespan
public bool GetCanHitSelf() => false;
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e9e6fd9b59fad3143ae9b96841feed5c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,24 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class AbilityExecutionContext
{
public PhotonView User { get; set; }
public Taggable UserTag { get; set; }
public Vector3 TargetPosition { get; set; }
public Taggable TargetTag { get; set; }
public float Cooldown { get; set; }
public float ManaCost { get; set; }
public float HealthCost { get; set; }
public float ClassResourceCost { get; set; }
public List<BaseEffect> Effects { get; set; }
public List<IAbilityModifier> Modifiers { get; set; }
public BaseAbility AbilityTemplate { get; set; }
public AbilityInstance AbilityInstance { get; set; }
// Add any other relevant execution data
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 22f275a658e2ac5468282b89eb52ff3b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public interface IAbilityModifier
{
void ApplyModifier(AbilityInstance instance);
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6587fbb018813714eb69ad7c9dbd596d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e83d84138bd06fe48927e60b0371577e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,102 @@
using UnityEngine;
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Events;
namespace Template_RuntimeInstance
{
public abstract class NetworkedAbilityBase : MonoBehaviourPunCallbacks
{
[Header("Visuals")]
[SerializeField] private GameObject hitParticlesPrefab;
[SerializeField] private GameObject visuals;
[Header("Common Settings")]
public PhotonView photonView;
public PhotonView owner;
public Taggable ownerTag;
public BaseAbility abilityTemplate;
public AbilityInstance abilityInstance;
public float lifeSpan;
public bool canHitSelf;
public AbilityExecutionContext context;
protected bool waitingForDestroy = false;
protected List<Taggable> targets = new List<Taggable>();
public UnityEvent<PhotonView, Taggable, List<Taggable>> onHitHappened = new UnityEvent<PhotonView, Taggable, List<Taggable>>();
protected virtual void Awake()
{
photonView = GetComponent<PhotonView>();
}
public virtual void Initialize(AbilityExecutionContext context, IAbilityProperties properties)
{
this.context = context;
owner = context.User;
ownerTag = context.UserTag;
abilityTemplate = context.AbilityTemplate;
lifeSpan = properties.GetLifeSpan();
canHitSelf = properties.GetCanHitSelf();
for (int i = 0; i < context.Modifiers.Count; i++)
{
context.Modifiers[i].ApplyModifier(context.AbilityInstance);
}
if (photonView.IsMine)
{
photonView.RPC(nameof(RPC_RemoteInit), RpcTarget.Others, AbilityIndexer.Instance.Abilities.IndexOf(abilityTemplate));
StartCoroutine(SelfDestruct());
}
}
[PunRPC]
protected virtual void RPC_RemoteInit(int abilityIndex)
{
abilityTemplate = AbilityIndexer.Instance.Abilities[abilityIndex];
}
[PunRPC]
private void RPC_DisableVisuals()
{
visuals.SetActive(false);
}
protected virtual void ApplyEffects(List<Taggable> targets)
{
if (!photonView.IsMine) return;
foreach (BaseEffect effect in context.Effects)
{
effect.ApplyEffect(ownerTag, targets);
}
}
protected virtual IEnumerator SelfDestruct()
{
yield return new WaitForSeconds(lifeSpan);
waitingForDestroy = true;
StartCoroutine(DelayedDestroy());
}
protected virtual IEnumerator DelayedDestroy()
{
photonView.RPC(nameof(RPC_DisableVisuals), RpcTarget.All);
yield return new WaitForSeconds(1.5f);
PhotonNetwork.Destroy(photonView);
}
protected virtual bool IsValidTarget(Taggable target)
{
return target != null &&
(canHitSelf || target != ownerTag) &&
target.IsValidTarget(abilityTemplate.targettingTags);
}
}
}

View File

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

View File

@ -0,0 +1,63 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Template_RuntimeInstance
{
public class NetworkedAntiProjectile : NetworkedAbilityBase
{
public bool followUser;
public GameObject visuals;
public UnityEvent onProjectileBlocked = new UnityEvent();
public override void Initialize(AbilityExecutionContext context, IAbilityProperties properties)
{
base.Initialize(context, properties);
if (properties is AntiProjectileAbilityProperties antiProjectileProps)
{
followUser = antiProjectileProps.followUser;
}
if (photonView.IsMine && followUser)
{
StartCoroutine(FollowUser());
}
}
private IEnumerator FollowUser()
{
while (!waitingForDestroy)
{
transform.position = owner.transform.position;
yield return null;
}
}
public void SendBlockNotice()
{
if (waitingForDestroy) return;
photonView.RPC(nameof(RPC_SendBlockNotice), RpcTarget.All);
}
[PunRPC]
private void RPC_SendBlockNotice()
{
waitingForDestroy = true;
onProjectileBlocked.Invoke();
if (!photonView.IsMine)
{
visuals.SetActive(false);
return;
}
StartCoroutine(DelayedDestroy());
}
}
}

View File

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

View File

@ -0,0 +1,90 @@
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Template_RuntimeInstance
{
public class NetworkedAreaOfEffect : NetworkedAbilityBase
{
public float radius;
public float telegraphDelay;
[SerializeField] protected GameObject telegraph;
[SerializeField] protected GameObject effectVisual;
public override void Initialize(AbilityExecutionContext context, IAbilityProperties properties)
{
base.Initialize(context, properties);
if (properties is AreaOfEffectAbilityProperties aoeProps)
{
radius = aoeProps.radius;
telegraphDelay = aoeProps.telegraphDelay;
}
if (photonView.IsMine)
{
StartCoroutine(ApplyTelegraphDelay());
}
}
protected virtual IEnumerator ApplyTelegraphDelay()
{
ShowTelegraph();
yield return new WaitForSeconds(telegraphDelay);
ApplyArea();
}
protected virtual void ApplyArea()
{
ShowEffectVisual();
CheckSurroundings();
}
protected virtual void CheckSurroundings()
{
Collider[] hits = Physics.OverlapSphere(transform.position, radius, LayerMask.GetMask("Targetable"));
targets.Clear();
foreach (Collider collider in hits)
{
Taggable target = collider.GetComponentInParent<Taggable>();
if (IsValidTarget(target))
{
targets.Add(target);
}
}
photonView.RPC(nameof(RPC_CheckSurroundings), RpcTarget.Others);
if (photonView.IsMine)
{
ApplyEffects(targets);
onHitHappened.Invoke(owner, ownerTag, targets);
}
}
[PunRPC]
protected virtual void RPC_CheckSurroundings()
{
// This method is called on other clients to sync the visual effects
ShowEffectVisual();
}
protected virtual void ShowTelegraph()
{
telegraph.SetActive(true);
effectVisual.SetActive(false);
}
protected virtual void ShowEffectVisual()
{
telegraph.SetActive(false);
effectVisual.SetActive(true);
}
}
}

View File

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

View File

@ -0,0 +1,73 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class NetworkedAreaOfEffectOverTime : NetworkedAreaOfEffect
{
public float duration;
public bool followUser;
public bool followTarget;
public bool damageFollowingTarget;
protected float endTime;
protected Taggable followingTargetTaggable;
public override void Initialize(AbilityExecutionContext context, IAbilityProperties properties)
{
base.Initialize(context, properties);
if (properties is AreaOfEffectOverTimeAbilityProperties aoeotProps)
{
duration = aoeotProps.duration;
followUser = aoeotProps.followUser;
followTarget = aoeotProps.followTarget;
damageFollowingTarget = aoeotProps.damageFollowingTarget;
}
if (photonView.IsMine)
{
if (followUser)
StartCoroutine(FollowTransform(owner.transform));
else if (followTarget && context.TargetTag != null)
{
followingTargetTaggable = context.TargetTag;
StartCoroutine(FollowTransform(followingTargetTaggable.transform));
}
}
}
protected override void ApplyArea()
{
base.ApplyArea();
StartCoroutine(ApplyAreaOverTime());
}
protected virtual IEnumerator ApplyAreaOverTime()
{
endTime = Time.time + duration;
while (Time.time < endTime)
{
yield return new WaitForSeconds(0.5f);
CheckSurroundings();
}
}
protected virtual IEnumerator FollowTransform(Transform target)
{
while (Time.time < endTime)
{
if (transform == null || target == null) break;
transform.position = target.position;
yield return new WaitForEndOfFrame();
}
}
protected override bool IsValidTarget(Taggable target)
{
return base.IsValidTarget(target) &&
(!followTarget || damageFollowingTarget || target != followingTargetTaggable);
}
}
}

View File

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

View File

@ -0,0 +1,79 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class NetworkedChanneling : NetworkedAbilityBase
{
public float radius;
public bool followUser;
private Coroutine channelingCoroutine;
public override void Initialize(AbilityExecutionContext context, IAbilityProperties properties)
{
base.Initialize(context, properties);
if (properties is ChanneledAbilityProperties channeledProps)
{
radius = channeledProps.radius;
followUser = channeledProps.followUser;
}
if (photonView.IsMine)
{
channelingCoroutine = StartCoroutine(ExecuteChanneling());
if (followUser)
StartCoroutine(FollowUser());
}
}
private IEnumerator ExecuteChanneling()
{
float endTime = Time.time + lifeSpan;
while (Time.time < endTime)
{
yield return new WaitForSeconds(0.5f);
CheckSurroundings();
}
}
private IEnumerator FollowUser()
{
while (channelingCoroutine != null)
{
transform.position = owner.transform.position;
yield return null;
}
}
private void CheckSurroundings()
{
Collider[] hits = Physics.OverlapSphere(transform.position, radius, LayerMask.GetMask("Targetable"));
targets.Clear();
foreach (Collider collider in hits)
{
Taggable target = collider.GetComponentInParent<Taggable>();
if (IsValidTarget(target))
{
targets.Add(target);
}
}
ApplyEffects(targets);
onHitHappened.Invoke(owner, ownerTag, targets);
}
protected override IEnumerator DelayedDestroy()
{
if (channelingCoroutine != null)
{
StopCoroutine(channelingCoroutine);
channelingCoroutine = null;
}
return base.DelayedDestroy();
}
}
}

View File

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

View File

@ -0,0 +1,52 @@
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class NetworkedProjectile : NetworkedAbilityBase
{
public float speed;
public bool canPierce;
public override void Initialize(AbilityExecutionContext context, IAbilityProperties properties)
{
base.Initialize(context, properties);
if (properties is ProjectileAbilityProperties projectileProps)
{
speed = projectileProps.projectileSpeed;
canPierce = projectileProps.canPierce;
}
}
private void Update()
{
if (!photonView.IsMine || waitingForDestroy) return;
transform.position += transform.forward * speed * Time.deltaTime;
}
private void OnTriggerEnter(Collider other)
{
if (waitingForDestroy) return;
Taggable target = other.GetComponentInParent<Taggable>();
if (!IsValidTarget(target)) return;
targets.Clear();
targets.Add(target);
onHitHappened.Invoke(owner, ownerTag, targets);
if (!photonView.IsMine) return;
ApplyEffects(targets);
if (!canPierce)
{
waitingForDestroy = true;
StartCoroutine(DelayedDestroy());
}
}
}
}

View File

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

View File

@ -0,0 +1,82 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class NetworkedSlash : NetworkedAbilityBase
{
public float range;
public bool regenHealthOnHit;
public bool regenManaOnHit;
public float healthOnHit;
public float manaOnHit;
[SerializeField] protected GameObject hitBox;
protected Health ownerHealth;
protected Mana ownerMana;
public override void Initialize(AbilityExecutionContext context, IAbilityProperties properties)
{
base.Initialize(context, properties);
if (properties is SlashAbilityProperties slashProps)
{
range = slashProps.range;
regenHealthOnHit = slashProps.regenHealthOnHit;
regenManaOnHit = slashProps.regenManaOnHit;
healthOnHit = slashProps.healthOnHit;
manaOnHit = slashProps.manaOnHit;
}
ownerHealth = owner.GetComponent<Health>();
ownerMana = owner.GetComponent<Mana>();
if (photonView.IsMine)
{
SetupHitBox();
CheckSurroundings();
}
}
private void SetupHitBox()
{
Vector3 newScale = hitBox.transform.localScale;
newScale.z = range;
hitBox.transform.localScale = newScale;
Vector3 newPosition = hitBox.transform.localPosition;
newPosition.z = range / 2;
hitBox.transform.localPosition = newPosition;
}
protected virtual void CheckSurroundings()
{
Collider[] hits = Physics.OverlapBox(hitBox.transform.position, hitBox.transform.localScale / 2, transform.rotation, LayerMask.GetMask("Targetable"));
targets.Clear();
foreach (Collider collider in hits)
{
Taggable target = collider.GetComponentInParent<Taggable>();
if (IsValidTarget(target))
{
targets.Add(target);
}
}
ApplyEffects(targets);
ApplyRegeneration(targets.Count);
onHitHappened.Invoke(owner, ownerTag, targets);
StartCoroutine(DelayedDestroy());
}
protected virtual void ApplyRegeneration(int hitCount)
{
if (regenHealthOnHit)
ownerHealth.ChangeValue(healthOnHit * hitCount);
if (regenManaOnHit)
ownerMana.ChangeValue(manaOnHit * hitCount);
}
}
}

View File

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

View File

@ -0,0 +1,46 @@
using Kryz.CharacterStats;
using Kryz.CharacterStats.Examples;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class NetworkedSummonedMinion : NetworkedAbilityBase
{
private CharacterStats minionStats;
public override void Initialize(AbilityExecutionContext context, IAbilityProperties properties)
{
base.Initialize(context, properties);
minionStats = GetComponent<CharacterStats>();
if (minionStats != null && photonView.IsMine)
{
InitializeStatsBasedOnOwner(context.User.GetComponent<CharacterStats>());
}
}
private void InitializeStatsBasedOnOwner(CharacterStats ownerStats)
{
// Scale minion stats based on owner's stats
minionStats.Strength.AddModifier(new StatModifier(ownerStats.Strength.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.Agility.AddModifier(new StatModifier(ownerStats.Agility.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.Intelligence.AddModifier(new StatModifier(ownerStats.Intelligence.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.Spirit.AddModifier(new StatModifier(ownerStats.Spirit.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.Vitality.AddModifier(new StatModifier(ownerStats.Vitality.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.AttackDamage.AddModifier(new StatModifier(ownerStats.AttackDamage.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.SpellDamage.AddModifier(new StatModifier(ownerStats.SpellDamage.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.CritChance.AddModifier(new StatModifier(ownerStats.CritChance.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.CritDamage.AddModifier(new StatModifier(ownerStats.CritDamage.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.MaxHealth.AddModifier(new StatModifier(ownerStats.MaxHealth.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.Armor.AddModifier(new StatModifier(ownerStats.Armor.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.MagicResistance.AddModifier(new StatModifier(ownerStats.MagicResistance.Value * GameConstants.CharacterStatsBalancing.PercentageStatScaleForMinions, StatModType.Flat, ownerStats));
minionStats.onUpdateStatValues.Invoke();
}
}
}

View File

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

View File

@ -0,0 +1,62 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class AbilityIndexer : MonoBehaviour
{
#region Singleton
private static AbilityIndexer _instance;
// Public reference to the singleton instance
public static AbilityIndexer Instance
{
get
{
// If the instance doesn't exist, try to find it in the scene
if (_instance == null)
{
_instance = FindObjectOfType<AbilityIndexer>();
// If it's still null, create a new GameObject and add the component
if (_instance == null)
{
GameObject singletonObject = new GameObject(typeof(AbilityIndexer).Name);
_instance = singletonObject.AddComponent<AbilityIndexer>();
}
}
return _instance;
}
}
#endregion
public List<BaseAbility> Abilities = new List<BaseAbility>();
protected void Awake()
{
// Ensure there's only one instance
if (_instance != null && _instance != this)
{
Destroy(gameObject);
return;
}
// If this is the first instance, set it as the singleton
_instance = this;
DontDestroyOnLoad(gameObject);
}
private void OnValidate()
{
if (Abilities == null) return;
foreach (BaseAbility baseAbility in Resources.FindObjectsOfTypeAll<BaseAbility>())
{
if (Abilities.Contains(baseAbility)) continue;
Abilities.Add(baseAbility);
}
}
}
}

View File

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

View File

@ -0,0 +1,149 @@
using Kryz.CharacterStats.Examples;
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class AbilityKeyBinder : MonoBehaviour
{
[Header("Listeners:")]
[SerializeField] private GameEventListener onLocalPlayerFainted;
[SerializeField] private GameEventListener onLocalPlayerPermaDeath;
[SerializeField] private GameEventListener onLocalPlayerRevived;
[Space]
[SerializeField] private BaseAbility ability;
[SerializeField] private GameKey key;
[SerializeField] private CastingStateController castingStateController;
[SerializeField] private GameEvent_AbilityKeyBinder onAbilityKeyBinderSpawned;
private PhotonView user;
private Taggable userTag;
private Mana mana;
public BaseAbility Ability => ability;
public GameKey GameKey => key;
Coroutine currentChanneling;
NetworkedChanneling networkedChanneling;
AbilityBindInstance abilityBindInstance;
AbilityCooldownTracker cooldownTracker;
bool isDead = false;
private void Awake()
{
user = GetComponentInParent<PhotonView>();
userTag = GetComponentInParent<Taggable>();
mana = GetComponentInParent<Mana>();
cooldownTracker = user.GetComponentInChildren<AbilityCooldownTracker>();
}
private void Start()
{
if (!user.IsMine)
{
enabled = false;
return;
}
onLocalPlayerFainted.Response.AddListener(() =>
{
isDead = true;
});
onLocalPlayerPermaDeath.Response.AddListener(() =>
{
isDead = true;
});
onLocalPlayerRevived.Response.AddListener(() =>
{
isDead = false;
});
onAbilityKeyBinderSpawned.Raise(this);
}
// Update is called once per frame
void Update()
{
if (isDead) return;
if (Input.GetKeyDown(key.keyCode))
{
if (abilityBindInstance != null)
abilityBindInstance.pressed.SetActive(true);
if (IsAbilityOffCooldown() && mana.EnoughMana(ability.manaCost))
{
if (ability is ChanneledAbility)
{
castingStateController.RequestAbilityChannel(ability, () =>
{
networkedChanneling = ((ChanneledAbility)ability).ExecuteChannel(user, userTag, ref currentChanneling);
if (ability.cooldown > 0)
{
cooldownTracker.StartAbilityCooldown(ability);
abilityBindInstance.StartCooldownTrackerUI();
}
});
}
else
{
castingStateController.RequestAbilityCast(ability, () =>
{
ability.Execute(user, userTag);
if (ability.cooldown > 0)
{
cooldownTracker.StartAbilityCooldown(ability);
abilityBindInstance.StartCooldownTrackerUI();
}
});
}
}
}
if (Input.GetKeyUp(key.keyCode))
{
if (abilityBindInstance != null)
abilityBindInstance.pressed.SetActive(false);
if (currentChanneling != null)
{
if (networkedChanneling != null)
{
networkedChanneling.StopCoroutine(currentChanneling);
}
else
{
StopCoroutine(currentChanneling);
}
castingStateController.ResetChannelingCast();
CastBarHandler.Instance.CancelChannelingOnButtonReleased();
}
if (networkedChanneling != null)
{
networkedChanneling.channeling = false;
networkedChanneling.DisableVisuals();
}
}
}
public void SetupAbilityBindInstance(AbilityBindInstance abilityBindInstance)
{
this.abilityBindInstance = abilityBindInstance;
mana.onResourceChanged.AddListener(OnManaChanged);
}
public void OnManaChanged(float currentMana)
{
abilityBindInstance.noMana.SetActive(!mana.EnoughMana(ability.manaCost));
}
public bool IsAbilityOffCooldown()
{
return ability.cooldown <= 0 || !cooldownTracker.OnCooldown(ability);
}
}
}

View File

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

View File

@ -0,0 +1,36 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Template_RuntimeInstance
{
public class AbilityManager : MonoBehaviour
{
private Dictionary<string, AbilityInstance> abilityInstances = new Dictionary<string, AbilityInstance>();
public AbilityInstance CreateAbilityInstance(BaseAbility abilityTemplate)
{
AbilityInstance instance = new AbilityInstance(abilityTemplate);
abilityInstances[instance.id] = instance;
return instance;
}
public AbilityInstance GetAbilityInstance(string id)
{
if (abilityInstances.TryGetValue(id, out AbilityInstance instance))
{
return instance;
}
return null;
}
public void RemoveAbilityInstance(string id)
{
if (abilityInstances.ContainsKey(id))
{
abilityInstances.Remove(id);
}
}
}
}

View File

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

View File

@ -1,20 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class BaseAbilityData
{
public Sprite Icon;
public List<TargetTag> targettingTags = new List<TargetTag>();
public List<GameTag> tags = new List<GameTag>();
public List<BaseEffect> abilityEffects = new List<BaseEffect>();
[Space]
public float castTime;
public float manaCost;
public float healthCost = 0;
public float classResourceCost = 0;
public float cooldown;
public bool castableWhileMoving;
public AbilityAnimationType animationType;
}

View File

@ -1,9 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class BaseAbilityInstance
{
public BaseAbilityData abilityData;
}

View File

@ -93,6 +93,8 @@ public class InstantValueEffect : BaseEffect
else if(stats.secondaryStatsDictionary.TryGetValue(statInfluence.statTag.name.ToLower(), out CharacterStat secondaryStat))
{
finalValue += secondaryStat.Value * statInfluence.percentInfluence;
}
if (statInfluence.statTag.name.ToLower().Contains("Attack")) damageType = DamageType.Attack;
else if (statInfluence.statTag.name.ToLower().Contains("Spell")) damageType = DamageType.Spell;

View File

@ -44,12 +44,6 @@ public class SummonAbility : BaseAbility
InitializeStatsBasedOnOwner(user);
}
public void AutoSummonOnSceneLoad(PhotonView user)
{
instantiatedMinion = PhotonNetwork.Instantiate("Abilities/" + minionPrefab.name, user.GetComponentInChildren<ProjectileSpawnLocationController>().transform.position, user.GetComponentInChildren<ProjectileSpawnLocationController>().transform.rotation);
InitializeStatsBasedOnOwner(user);
}
private void InitializeStatsBasedOnOwner(PhotonView user)
{
ownerStats = user.GetComponent<CharacterStats>();

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: b3e9fe72bbbe46648920a316a683101f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,134 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "Awakening", menuName = "RiftMayhem/AwakeningSystem/Awakenings/new BaseAwakening", order = 0)]
public class Awakening : ScriptableObject
{
public AwakeningData data;
public bool AllRequirementsMet(List<Awakening> unlockedAwakenings)
{
for (int i = 0; i < data.requiredAwakenings.Count; i++)
{
if (!unlockedAwakenings.Contains(data.requiredAwakenings[i])) return false;
}
return true;
}
}
[System.Serializable]
public class AwakeningInstance
{
public AwakeningData data;
public bool AllRequirementsMet(List<Awakening> unlockedAwakenings)
{
for (int i = 0; i < data.requiredAwakenings.Count; i++)
{
if (!unlockedAwakenings.Contains(data.requiredAwakenings[i])) return false;
}
return true;
}
}
[System.Serializable]
public class AwakeningData
{
public string Name;
public string Description;
public int CurrentPoints;
public int MaxPoints;
public List<Awakening> requiredAwakenings = new List<Awakening>();
[Space]
public int StrengthBonus;
public int AgilityBonus;
public int IntelligenceBonus;
public int SpiritBonus;
public int VitalityBonus;
[Space]
public float StrengthPercentBonus;
public float AgilityPercentBonus;
public float IntelligencePercentBonus;
public float SpiritPercentBonus;
public float VitalityPercentBonus;
[Space]
public int AttackDamageBonus;
public int SpellDamageBonus;
public int CritChanceBonus;
public int CritDamageBonus;
public int MaxHealthBonus;
public int ArmorBonus;
public int MagicResistanceBonus;
[Space]
public float AttackDamagePercentBonus;
public float SpellDamagePercentBonus;
public float CritChancePercentBonus;
public float CritDamagePercentBonus;
public float MaxHealthPercentBonus;
public float ArmorPercentBonus;
public float MagicResistancePercentBonus;
public AwakeningData()
{
Name = "";
Description = "";
CurrentPoints = 0;
MaxPoints = 1;
requiredAwakenings = new List<Awakening>();
}
public AwakeningData(string name, string description)
{
Name = name;
Description = description;
CurrentPoints = 0;
MaxPoints = 1;
requiredAwakenings = new List<Awakening>();
}
public AwakeningData(string name, string description, int currentPoints, int totalPoints, List<Awakening> requirements)
{
Name = name;
Description = description;
CurrentPoints = currentPoints;
MaxPoints = totalPoints;
requiredAwakenings = requirements;
}
public AwakeningData(AwakeningData data)
{
this.Name = data.Name;
this.Description = data.Description;
this.CurrentPoints = data.CurrentPoints;
this.MaxPoints = data.MaxPoints;
this.requiredAwakenings = data.requiredAwakenings;
this.StrengthBonus = data.StrengthBonus;
this.AgilityBonus = data.AgilityBonus;
this.IntelligenceBonus = data.IntelligenceBonus;
this.SpiritBonus = data.SpiritBonus;
this.VitalityBonus = data.VitalityBonus;
this.StrengthPercentBonus = data.StrengthPercentBonus;
this.AgilityPercentBonus = data.AgilityPercentBonus;
this.IntelligencePercentBonus = data.IntelligencePercentBonus;
this.SpiritPercentBonus = data.SpiritPercentBonus;
this.VitalityPercentBonus = data.VitalityPercentBonus;
this.AttackDamageBonus = data.AttackDamageBonus;
this.SpellDamageBonus = data.SpellDamageBonus;
this.CritChanceBonus = data.CritChanceBonus;
this.CritDamageBonus = data.CritDamageBonus;
this.MaxHealthBonus = data.MaxHealthBonus;
this.ArmorBonus = data.ArmorBonus;
this.MagicResistanceBonus = data.MagicResistanceBonus;
this.AttackDamagePercentBonus = data.AttackDamagePercentBonus;
this.SpellDamagePercentBonus = data.SpellDamagePercentBonus;
this.CritChancePercentBonus = data.CritChancePercentBonus;
this.CritDamagePercentBonus = data.CritDamagePercentBonus;
this.MaxHealthPercentBonus = data.MaxHealthPercentBonus;
this.ArmorPercentBonus = data.ArmorPercentBonus;
this.MagicResistancePercentBonus = data.MagicResistancePercentBonus;
}
}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: bac7dcb65e711114fa3203ffde968f74
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,18 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpecificDamageIncreaseAwakening : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@ -1,9 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ClassAwakenings
{
public List<Awakening> AllAvailableAwakenings = new List<Awakening>();
}

View File

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

View File

@ -1,34 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAwakenings : MonoBehaviour
{
private List<BaseAbility> unlockedAbilities = new List<BaseAbility>();
private List<Awakening> unlockedAwakenings = new List<Awakening>();
public void UnlockAbility(BaseAbility ability)
{
if (unlockedAbilities.Contains(ability)) return;
unlockedAbilities.Add(ability);
}
public void UnlockAwakening(Awakening awakening)
{
if (unlockedAwakenings.Contains(awakening)) return;
if (!awakening.AllRequirementsMet(unlockedAwakenings)) return;
unlockedAwakenings.Add(awakening);
}
public bool IsAbilityUnlocked(BaseAbility ability)
{
return unlockedAbilities.Contains(ability);
}
public bool IsAwakeningUnlocked(Awakening awakening)
{
return unlockedAwakenings.Contains(awakening);
}
}

View File

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

View File

@ -1,70 +0,0 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System;
public partial class AbilityEditorWindow : EditorWindow
{
private Vector2 scrollPosition;
private string searchQuery = "";
private AbilityCreationData abilityData;
private Type selectedAbilityType;
private Dictionary<string, Type> abilityTypes;
[MenuItem("Tools/Ability Editor")]
public static void ShowWindow()
{
GetWindow<AbilityEditorWindow>("Ability Editor");
}
private void OnEnable()
{
InitializeData();
CacheAbilityTypes();
}
private void InitializeData()
{
abilityData = new AbilityCreationData();
}
private void CacheAbilityTypes()
{
// Cache all ability types that inherit from BaseAbility
abilityTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => type.IsClass && !type.IsAbstract && typeof(BaseAbility).IsAssignableFrom(type))
.ToDictionary(type => type.Name, type => type);
}
private void OnGUI()
{
DrawHeader();
DrawSearchBar();
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
DrawAbilityCreation();
EditorGUILayout.Space(20);
DrawExistingAbilities();
EditorGUILayout.EndScrollView();
}
private void DrawHeader()
{
EditorGUILayout.Space(10);
GUILayout.Label("Ability Editor", EditorStyles.boldLabel);
EditorGUILayout.Space(5);
}
private void DrawSearchBar()
{
EditorGUILayout.BeginHorizontal();
searchQuery = EditorGUILayout.TextField("Search", searchQuery);
if (GUILayout.Button("Clear", GUILayout.Width(50)))
searchQuery = "";
EditorGUILayout.EndHorizontal();
}
}

View File

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

View File

@ -1,133 +0,0 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System;
public partial class AbilityEditorWindow
{
private void DrawAbilityCreation()
{
EditorGUILayout.BeginVertical("box");
EditorGUILayout.LabelField("Create New Ability", EditorStyles.boldLabel);
DrawAbilityTypeSelection();
if (selectedAbilityType != null)
{
DrawBasicFields();
DrawTypeSpecificFields();
EditorGUILayout.Space(10);
if (GUILayout.Button("Create Ability"))
{
CreateAbility();
}
}
EditorGUILayout.EndVertical();
}
private void DrawAbilityTypeSelection()
{
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Ability Type", EditorStyles.boldLabel);
string[] typeNames = abilityTypes.Keys.ToArray();
int currentIndex = Array.IndexOf(typeNames, selectedAbilityType?.Name ?? "");
int newIndex = EditorGUILayout.Popup("Select Type", currentIndex, typeNames);
if (newIndex != currentIndex && newIndex >= 0)
{
selectedAbilityType = abilityTypes[typeNames[newIndex]];
abilityData.typeSpecificData.Clear();
}
}
private void DrawBasicFields()
{
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Basic Settings", EditorStyles.boldLabel);
abilityData.name = EditorGUILayout.TextField("Name", abilityData.name);
abilityData.description = EditorGUILayout.TextArea(abilityData.description, GUILayout.Height(60));
abilityData.icon = (Sprite)EditorGUILayout.ObjectField("Icon", abilityData.icon, typeof(Sprite), false);
abilityData.animationType = (AbilityAnimationType)EditorGUILayout.EnumPopup("Animation Type", abilityData.animationType);
EditorGUILayout.Space(5);
EditorGUILayout.LabelField("Costs and Timing", EditorStyles.boldLabel);
abilityData.manaCost = EditorGUILayout.FloatField("Mana Cost", abilityData.manaCost);
abilityData.healthCost = EditorGUILayout.FloatField("Health Cost", abilityData.healthCost);
abilityData.cooldown = EditorGUILayout.FloatField("Cooldown", abilityData.cooldown);
abilityData.castTime = EditorGUILayout.FloatField("Cast Time", abilityData.castTime);
abilityData.castableWhileMoving = EditorGUILayout.Toggle("Castable While Moving", abilityData.castableWhileMoving);
}
private void DrawTypeSpecificFields()
{
if (selectedAbilityType == null) return;
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Type Specific Settings", EditorStyles.boldLabel);
if (selectedAbilityType == typeof(ProjectileAbility))
{
DrawProjectileFields();
}
else if (selectedAbilityType == typeof(AreaOfEffectAbility))
{
DrawAreaOfEffectFields();
}
else if (selectedAbilityType == typeof(ChanneledAbility))
{
DrawChanneledFields();
}
}
private void DrawProjectileFields()
{
float projectileSpeed = abilityData.GetOrCreateTypeSpecific<float>("projectileSpeed");
projectileSpeed = EditorGUILayout.FloatField("Projectile Speed", projectileSpeed);
abilityData.typeSpecificData["projectileSpeed"] = projectileSpeed;
float lifeSpan = abilityData.GetOrCreateTypeSpecific<float>("lifeSpan");
lifeSpan = EditorGUILayout.FloatField("Life Span", lifeSpan);
abilityData.typeSpecificData["lifeSpan"] = lifeSpan;
bool canPierce = abilityData.GetOrCreateTypeSpecific<bool>("canPierce");
canPierce = EditorGUILayout.Toggle("Can Pierce", canPierce);
abilityData.typeSpecificData["canPierce"] = canPierce;
GameObject projectilePrefab = abilityData.GetOrCreateTypeSpecific<GameObject>("projectilePrefab");
projectilePrefab = (GameObject)EditorGUILayout.ObjectField("Projectile Prefab",
projectilePrefab, typeof(GameObject), false);
abilityData.typeSpecificData["projectilePrefab"] = projectilePrefab;
}
private void DrawAreaOfEffectFields()
{
float radius = abilityData.GetOrCreateTypeSpecific<float>("radius");
radius = EditorGUILayout.FloatField("Radius", radius);
abilityData.typeSpecificData["radius"] = radius;
float duration = abilityData.GetOrCreateTypeSpecific<float>("duration");
duration = EditorGUILayout.FloatField("Duration", duration);
abilityData.typeSpecificData["duration"] = duration;
GameObject aoePrefab = abilityData.GetOrCreateTypeSpecific<GameObject>("aoePrefab");
aoePrefab = (GameObject)EditorGUILayout.ObjectField("AoE Prefab",
aoePrefab, typeof(GameObject), false);
abilityData.typeSpecificData["aoePrefab"] = aoePrefab;
}
private void DrawChanneledFields()
{
float channelDuration = abilityData.GetOrCreateTypeSpecific<float>("channelDuration");
channelDuration = EditorGUILayout.FloatField("Channel Duration", channelDuration);
abilityData.typeSpecificData["channelDuration"] = channelDuration;
bool canMove = abilityData.GetOrCreateTypeSpecific<bool>("canMove");
canMove = EditorGUILayout.Toggle("Can Move While Channeling", canMove);
abilityData.typeSpecificData["canMove"] = canMove;
}
}

View File

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

Some files were not shown because too many files have changed in this diff Show More