Compare commits
1 Commits
master
...
SOTemplate
Author | SHA1 | Date | |
---|---|---|---|
ddd7caad77 |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3c7acee50b617343adac7c021b18fd4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7745cb695af3bf4cbc59d105bb761ae
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b5716c4ad6e39c409e2e8217f2fcdec
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4809e1c0c1448448b74cf90992702b2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcd80a6f46ee35e4ca73befb46c40e7d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fd10732ea3f0264a82b38345f89bdc4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09d6928bbd92a3c4890a0be6e545de0e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6519cff19268c1d42ac22ac8367fafbd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec6e4aa3effacb4468d53cb718f1c98a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95e386d09f94bf444aacbb26ed5182db
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 171d73bfd42fe054ca28b6a8f4ef9358
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4aedcd11782e6544e8786936943468a6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07d783530f392274182059bc1f32be1e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a746ba64a0d9204c89fbf784ab69339
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cbcbf086a3625ed4b92cad3caffbd9b2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4bf69549f85408344a7d334b55755d93
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b45f42084a741f044ac75c6489a6c53e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b55bef88a4c5fd44a22739a6ec6ebeb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d98ad1e252315646adbbd532c2ec6ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ebea300a1db6cf4aa2fb9eba0283b0d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a69d40a56dc8f7d49989c92a78617dd1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e523d871d41ec84e8429ff314daf3fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39d9378d941174144b4d691088981463
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2332831b88d738446aa91cf6c007add3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8134918c95b031b49b243d8588a9a667
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 064c44c8976c7b94b8663224456b2300
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 541d4fe7cefd00548bd59a7f5109c387
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9e6fd9b59fad3143ae9b96841feed5c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 504972c68665c9048b13ace4c82b2bcd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22f275a658e2ac5468282b89eb52ff3b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,11 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Template_RuntimeInstance
|
||||
{
|
||||
public interface IAbilityModifier
|
||||
{
|
||||
void ApplyModifier(AbilityInstance instance);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7acc8438eba362f44900e746928e422b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6587fbb018813714eb69ad7c9dbd596d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e83d84138bd06fe48927e60b0371577e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50bdce70855772146bb66c989741fe12
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b30ab95901978444a92c50fbb1b9c7c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b773c4ada4c470343a007e8dce390ce0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bcdcd847e0509447a00245e99d943aa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89f072756f5993f4d88a1556a93f3614
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e997bda1384dc746886206fbd69e410
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31d18d3d362ad814eb76d79edb779a50
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8be85325eb19ec4aae2ce7a7f0b5a41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a115334de21b946428e94622ccf94960
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a0a457ad3799e24ba58619e9cdff270
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bebd20e6ca211ad4da2daaa3fea134e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user