예제 #1
0
        public void CastSubSpell(SubSpell subSpell, Target source, Target target)
        {
            if (!source.IsValid)
            {
                Debug.LogWarning($"Invalid source while casting SubSpell: {subSpell}");
                return;
            }

            if (!target.IsValid)
            {
                Debug.LogWarning($"Invalid target while casting SubSpell: {subSpell}");
                return;
            }

            Assert.IsNotNull(subSpell);

            if (_instances.ContainsKey(subSpell))
            {
                // Max instances of this SubSpell casted
                if (_instances[subSpell] >= subSpell.MaxInstances.GetValue(Stacks))
                {
                    return;
                }

                _instances[subSpell] += 1;
            }
            else
            {
                _instances.Add(subSpell, 1);
            }

            var handler = new SubSpellHandler(this, subSpell, source, target);

            _children.Add(handler);
            Event?.Invoke(this, SpellEvent.SubSpellCasted, handler);
        }
예제 #2
0
        public void Initialize(SubSpellHandler handler, ProjectileData projectileData)
        {
            _projectile = projectileData;
            _handler    = handler;

            // Setup RigidBody to handle collisions
            var body = GetComponentInChildren <Rigidbody>();

            if (body == null)
            {
                body = gameObject.AddComponent <Rigidbody>();
            }
            body.isKinematic = false;
            body.useGravity  = false;

            // Bake source point
            if (handler.Source.Type == TargetType.Character)
            {
                _spawnPoint = handler.Source.Character.GetNodeTransform(_projectile.SpawnNode).position;
            }
            else
            {
                _spawnPoint = handler.Source.Transform.position;
            }

            if (_projectile.Type == ProjectileType.Targeted && handler.Target.IsValid)
            {
                TargetUtility.DebugDraw(handler.Target, Color.blue);

                // ReTargeting to specific transform of character
                if (handler.Target.Type == TargetType.Character)
                {
                    _target = new Target(handler.Target.Character.GetNodeTransform(_projectile.TargetNode));
                }
                else
                {
                    _target = handler.Target;
                }
            }

            // Get initial direction
            if (_projectile.Type == ProjectileType.Directional)
            {
                var direction = handler.Source.Forward;

                // If target is specified, use it
                if (handler.Target.HasPosition)
                {
                    direction   = handler.Target.Position - _spawnPoint;
                    direction.y = 0;
                    direction.Normalize();
                }

                NavMesh.Raycast(_spawnPoint, _spawnPoint + direction * 100f, out var hit, NavMesh.AllAreas);
                _target = new Target(hit.position);
            }

            // Resolve stacked properties
            _timer       = projectileData.TimeToLive.GetValue(handler.Stacks);
            _speed       = projectileData.Speed.GetValue(handler.Stacks);
            _maxDistance = projectileData.MaxDistance.GetValue(handler.Stacks);

            // Initial positioning
            transform.position = _spawnPoint;
            //transform.rotation = Quaternion.LookRotation(_direction);

            IsActive = true;
        }