コード例 #1
0
        public SpawnCharacter(SpawnCharacterAction config, EntitySpawner entitySpawner, Character caster,
                              TemplateArgs args, Environment environment, SkillId skillId,
                              HeroAndMonsterConfig hamc)
        {
            this.config        = config;
            this.entitySpawner = entitySpawner;
            this.caster        = caster;
            this.args          = args;
            this.environment   = environment;
            this.skillId       = skillId;
            this.hamc          = hamc;

            entityGroupOfCaster = caster.GameObject().GetComponent <EntityReference>().Entity.Group;
            FrameAndSecondsConverter fasc = FrameAndSecondsConverter._30Fps;

            spawnDelay = fasc.FramesToSeconds(config.delay);
            vfxDelay   = fasc.FramesToSeconds(config.vfxDelay);
            defaultEntityGroupOfMinion = hamc.FindBasicStats(new CharacterId(config.groupId, config.subId)).team;

            if (config.spawnCount > 0)
            {
                Vector3 spawnPosition = CalculateSpawnPosition();
                spawnPositions.Add(spawnPosition);
                if (spawnDelay <= 0)
                {
                    Spawn(spawnPosition);
                }

                if (vfxDelay <= 0)
                {
                    PlayVfx(spawnPosition);
                }
            }
        }
コード例 #2
0
            public void Demangle(DemanglingContext context)
            {
                // Whether the first type in the BareFunctionType is a return
                // type or parameter depends on the context in which it
                // appears.
                //
                // * Templates and functions in a type or parameter position
                // always have return types.
                //
                // * Non-template functions that are not in a type or parameter
                // position do not have a return type.
                //
                // We know we are not printing a type, so we only need to check
                // whether this is a template.
                //
                // For the details, see
                // http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.function-type
                TemplateArgs templateArgs = Name.GetTemplateArgs();

                if (templateArgs != null)
                {
                    context.Stack.Push(templateArgs);
                    Type.Demangle(context);
                    context.Writer.Append(" ");
                }

                context.Inner.Push(this);
                Name.Demangle(context);
                if (context.Inner.Count > 0)
                {
                    context.Inner.Pop().DemangleAsInner(context);
                }
            }
コード例 #3
0
        public static IParsingResult Parse(ParsingContext context)
        {
            RewindState    rewind = context.RewindState;
            IParsingResult name   = SimpleId.Parse(context);

            if (name != null)
            {
                return(name);
            }
            if (context.Parser.VerifyString("on"))
            {
                IParsingResult operatorName = OperatorName.Parse(context);

                if (operatorName != null)
                {
                    IParsingResult arguments = TemplateArgs.Parse(context);

                    return(new Operator(operatorName, arguments));
                }
                context.Rewind(rewind);
                return(null);
            }
            if (context.Parser.VerifyString("dn"))
            {
                return(DestructorName.Parse(context));
            }
            return(null);
        }
コード例 #4
0
        public override void OnDetach(Character target)
        {
            base.OnDetach(target);
            ResumeAnimation();
            TemplateArgs args = new TemplateArgs();

            args.SetEntry(TemplateArgsName.Position, (Vector2)target.Position());
            info.ShowParentSkill().TriggerEventWithId(info.Fmc.eid, args);
        }
コード例 #5
0
        /// <summary>
        /// Конструктор.
        /// </summary>
        public SchemeView()
            : base()
        {
            maxComponentID = 0;
            templateArgs   = new TemplateArgs();

            SchemeDoc  = new SchemeDocument();
            Components = new SortedList <int, BaseComponent>();
            LoadErrors = new List <string>();
        }
コード例 #6
0
 private void Notify()
 {
     if (elapsed >= notifyAt && !isNotified)
     {
         isNotified = true;
         TemplateArgs args = new TemplateArgs();
         args.SetEntry(TemplateArgsName.Position, teleportPosition);
         skill.TriggerEventWithId(info.notiEventId, args);
     }
 }
コード例 #7
0
            public void Demangle(DemanglingContext context)
            {
                TemplateArgs args = Type.GetTemplateArgs();

                context.Writer.EnsureSpace();
                if (args != null)
                {
                    context.Stack.Push(args);
                }
                Type.Demangle(context);
            }
コード例 #8
0
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        public SchemeView(View viewEntity)
            : base(viewEntity)
        {
            maxComponentID   = 0;
            templateArgs     = new TemplateArgs(Args);
            templateBindings = null;

            SchemeDoc = new SchemeDocument {
                SchemeView = this
            };
            Components = new SortedList <int, ComponentBase>();
            LoadErrors = new List <string>();
        }
コード例 #9
0
ファイル: SimpleId.cs プロジェクト: pgielda/CxxDemangler
        public static IParsingResult Parse(ParsingContext context)
        {
            IParsingResult name = SourceName.Parse(context);

            if (name != null)
            {
                IParsingResult arguments = TemplateArgs.Parse(context);

                return(new SimpleId(name, arguments));
            }

            return(null);
        }
コード例 #10
0
            public void DemangleAsInner(DemanglingContext context)
            {
                TemplateArgs templateArgs = Name.GetTemplateArgs();

                if (templateArgs != null)
                {
                    context.Stack.Push(templateArgs);
                    Type.DemangleWithoutType(context);
                }
                else
                {
                    Type.DemangleWithType(context);
                }
            }
コード例 #11
0
        public override void OnBeReplaced(Character target, Modifier byModifier)
        {
            base.OnBeReplaced(target, byModifier);
            if (byModifier.Type() == ModifierType.Freeze)
            {
                targetAnimationComponent.Animation.UnpauseAnimation();
                return;
            }

            targetAnimationComponent.Animation.PlayAnimation(AnimationName.IDLE, 1, PlayMethod.Crossfade, 0.2f);
            TemplateArgs args = new TemplateArgs();

            args.SetEntry(TemplateArgsName.Position, (Vector2)target.Position());
            info.ShowParentSkill().TriggerEventWithId(info.Fmc.eid, args);
        }
コード例 #12
0
ファイル: Name.cs プロジェクト: pgielda/CxxDemangler
        public static IParsingResultExtended Parse(ParsingContext context)
        {
            RewindState            rewind = context.RewindState;
            IParsingResultExtended name   = NestedName.Parse(context);

            if (name != null)
            {
                return(name);
            }

            name = UnscopedName.Parse(context);
            if (name != null)
            {
                if (context.Parser.Peek == 'I')
                {
                    context.SubstitutionTable.Add(name);
                    TemplateArgs args = TemplateArgs.Parse(context);

                    if (args == null)
                    {
                        context.Rewind(rewind);
                        return(null);
                    }

                    return(new UnscopedTemplate(name, args));
                }
                else
                {
                    return(name);
                }
            }

            name = UnscopedTemplateName.Parse(context);
            if (name != null)
            {
                TemplateArgs args = TemplateArgs.Parse(context);

                if (args == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }

                return(new UnscopedTemplate(name, args));
            }

            return(LocalName.Parse(context));
        }
コード例 #13
0
        public void TriggerEventWithId(int id, TemplateArgs args = null)
        {
            for (int i = pendingEventFrames.Count - 1; i >= 0; i--)
            {
                BaseEvent ef = pendingEventFrames[i];
                if (ef.ShowTrigger().ShowTriggerType() != TriggerType.Event)
                {
                    continue;
                }

                EventBasedTrigger trigger = (EventBasedTrigger)ef.ShowTrigger();
                if (trigger.id != id)
                {
                    continue;
                }

                Trigger(ef, args);
            }
        }
コード例 #14
0
        public static IParsingResult Parse(ParsingContext context)
        {
            IParsingResult param = TemplateParam.Parse(context);

            if (param != null)
            {
                TemplateArgs   args   = TemplateArgs.Parse(context);
                IParsingResult result = new Template(param, args);

                context.SubstitutionTable.Add(result);
                return(result);
            }

            IParsingResult decltype = Decltype.Parse(context);

            if (decltype != null)
            {
                context.SubstitutionTable.Add(decltype);
                return(decltype);
            }

            return(Substitution.Parse(context));
        }
コード例 #15
0
        protected void Trigger(BaseEvent be, TemplateArgs args = null)
        {
            try {
                if (!IsEventTriggerable(be))
                {
                    return;
                }

                BaseAction ba         = be.ShowAction();
                ActionType actionType = ba.ShowActionType();
                switch (actionType)
                {
                case ActionType.CastProjectile:
                case ActionType.Impact:
                    List <ProjectileComponent> justLaunchedProjectiles = LaunchProjectiles(be);
                    projectiles.AddRange(justLaunchedProjectiles);
                    break;

                default:
                    Loopable loopable = loopableElementFactory.Produce(
                        caster, this, config.ShowSkillId(), be, config.ShowSkillCastingSource(), args
                        );
                    loopableElements.Insert(0, loopable);
                    if (actionType == ActionType.Jump)
                    {
                        jumps.Add((Jump)loopable);
                    }
                    OnLoopableElementProduction(be, loopable);
                    break;
                }
            }
            catch (Exception e) {
                Exception ex = new Exception("Error trigger event of skill id " + config.ShowSkillId(), e);
                DLog.LogException(ex);
            }
        }
コード例 #16
0
 public Template(IParsingResult parameter, TemplateArgs arguments)
 {
     Parameter = parameter;
     Arguments = arguments;
 }
コード例 #17
0
ファイル: Name.cs プロジェクト: pgielda/CxxDemangler
 public UnscopedTemplate(IParsingResultExtended name, TemplateArgs args)
 {
     Name = name;
     Args = args;
 }
コード例 #18
0
 public VendorExtension(IParsingResult name, TemplateArgs arguments, IParsingResult type)
 {
     Name      = name;
     Arguments = arguments;
     Type      = type;
 }
コード例 #19
0
 public TemplateTemplate(IParsingResultExtended type, TemplateArgs arguments)
 {
     Type      = type;
     Arguments = arguments;
 }
コード例 #20
0
        public static IParsingResultExtended Parse(ParsingContext context)
        {
            IParsingResultExtended type = BuiltinType.Parse(context);

            if (type != null)
            {
                return(type);
            }

            type = ClassEnumType.Parse(context);
            if (type != null)
            {
                return(AddToSubstitutionTable(context, type));
            }

            RewindState rewind = context.RewindState;

            type = Substitution.Parse(context);
            if (type != null)
            {
                if (context.Parser.Peek != 'I')
                {
                    return(type);
                }

                context.Rewind(rewind);
            }

            type = FunctionType.Parse(context) ?? ArrayType.Parse(context) ?? PointerToMemberType.Parse(context);
            if (type != null)
            {
                return(AddToSubstitutionTable(context, type));
            }

            type = TemplateParam.Parse(context);
            if (type != null)
            {
                if (context.Parser.Peek != 'I')
                {
                    return(AddToSubstitutionTable(context, type));
                }

                context.Rewind(rewind);
            }

            type = TemplateTemplateParam.Parse(context);
            if (type != null)
            {
                TemplateArgs arguments = TemplateArgs.Parse(context);

                if (arguments == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }

                return(AddToSubstitutionTable(context, new TemplateTemplate(type, arguments)));
            }

            type = Decltype.Parse(context);
            if (type != null)
            {
                return(type);
            }

            CvQualifiers qualifiers = CvQualifiers.Parse(context);

            if (qualifiers != null)
            {
                type = Parse(context);
                if (type == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }

                if (type is BuiltinType)
                {
                    return(new QualifiedBuiltin(qualifiers, type));
                }
                return(AddToSubstitutionTable(context, new Qualified(qualifiers, type)));
            }

            if (context.Parser.VerifyString("P"))
            {
                type = Parse(context);
                if (type == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }
                return(AddToSubstitutionTable(context, new PointerTo(type)));
            }

            if (context.Parser.VerifyString("R"))
            {
                type = Parse(context);
                if (type == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }
                return(AddToSubstitutionTable(context, new LvalueRef(type)));
            }

            if (context.Parser.VerifyString("O"))
            {
                type = Parse(context);
                if (type == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }
                return(AddToSubstitutionTable(context, new RvalueRef(type)));
            }

            if (context.Parser.VerifyString("C"))
            {
                type = Parse(context);
                if (type == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }
                return(AddToSubstitutionTable(context, new Complex(type)));
            }

            if (context.Parser.VerifyString("G"))
            {
                type = Parse(context);
                if (type == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }
                return(AddToSubstitutionTable(context, new Imaginary(type)));
            }

            if (context.Parser.VerifyString("U"))
            {
                IParsingResult name = SourceName.Parse(context);

                if (name == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }

                TemplateArgs arguments = TemplateArgs.Parse(context);

                type = Parse(context);
                return(AddToSubstitutionTable(context, new VendorExtension(name, arguments, type)));
            }

            if (context.Parser.VerifyString("Dp"))
            {
                type = Parse(context);
                if (type == null)
                {
                    context.Rewind(rewind);
                    return(null);
                }
                return(AddToSubstitutionTable(context, new PackExtension(type)));
            }

            return(null);
        }
コード例 #21
0
        public SsarTuple <Entity, IPromise <Entity> > Spawn(BaseEvent instruction,
                                                            Character caster, Skill parentSkill,
                                                            TemplateArgs preferedArgs = null)
        {
            CastProjectileAction cpa = (CastProjectileAction)instruction.ShowAction();
            BaseProjectile       projectileConfig = cpa.ShowProjectile();
            ProjectileType       projectileType   = projectileConfig.ShowProjectileType();

            TemplateArgs      args             = new TemplateArgs();
            Entity            projectileEntity = null;
            IPromise <Entity> creationPromise  = null;
            Vector2           relativePos      = Vector2.zero;
            string            prefabPath       = String.Empty;
            Entity            casterEntity     = promiseWorld.GetEntityById(caster.Id());
            bool found;
            List <CastProjectileAction.Lifetime> lifetimes = null;
            TrajectoryConfig   trajectoryConfig            = null;
            DamageTickerConfig damageTickerConfig          = projectileConfig.damageTickerConfig;
            List <HitBoxShape> hitBoxes      = new List <HitBoxShape>();
            Vector2            pivotPosition = caster.Position();
            UsageGoal          usageGoal     = cpa is ImpactAction ? UsageGoal.CollisionDetection : UsageGoal.DamageDealing;
            int  targetLockingDuration       = 0;
            int  targetLockingEventId        = -1;
            bool targetLockingClampY         = false;

            switch (projectileType)
            {
            case ProjectileType.Melee:
                MeleeProjectileConfig meleeProjectileConfig = (MeleeProjectileConfig)projectileConfig;
                HitBoxShape           firstHitBox           = meleeProjectileConfig.hitBoxes[0];
                hitBoxes.AddRange(meleeProjectileConfig.hitBoxes);
                relativePos = firstHitBox.ShowRelativePositionOfCenterPivot()
                              .FlipFollowDirection(caster.FacingDirection());
                prefabPath = meleeProjectilePrefabPath;
                lifetimes  = meleeProjectileConfig.lifetimes;
                FollowerMode followerMode = meleeProjectileConfig.anchor.ShowFollowerMode();
                switch (followerMode)
                {
                case FollowerMode.None:
                    StationaryTrajectoryConfig stationaryTrajectoryConfig  = new StationaryTrajectoryConfig();
                    CastProjectileAction.NoneAnchorFollower anchorFollower = (CastProjectileAction.NoneAnchorFollower)meleeProjectileConfig.anchor;
                    stationaryTrajectoryConfig.directionReverse = anchorFollower.directionReverse;
                    trajectoryConfig = stationaryTrajectoryConfig;
                    break;

                case FollowerMode.Caster:
                    stationaryTrajectoryConfig = new StationaryTrajectoryConfig();
                    stationaryTrajectoryConfig.followCaster = true;
                    trajectoryConfig = stationaryTrajectoryConfig;
                    break;

                case FollowerMode.Joint:
                    JointFollowerTrajectoryConfig jftc = new JointFollowerTrajectoryConfig();
                    JointAnchorFollower           jaf  = (JointAnchorFollower)meleeProjectileConfig.anchor;
                    jftc.joint             = jaf.joint;
                    jftc.rotation          = jaf.rotation;
                    jftc.rotationDirection = jaf.rotationDirection;
                    jftc.axis        = jaf.axis;
                    trajectoryConfig = jftc;
                    break;

                default:
                    throw new Exception(string.Format(
                                            "Missing logic to create config of FollowerMode '{0}'", followerMode
                                            ));
                }
                break;

            case ProjectileType.Ranger:
                RangerProjectileConfig rangerProjectileConfig = (RangerProjectileConfig)projectileConfig;
                if (rangerProjectileConfig.useOwnPivotPosition)
                {
                    pivotPosition = rangerProjectileConfig.pivotPosition;
                }
                relativePos = rangerProjectileConfig.hitBox.ShowRelativePositionOfCenterPivot();
                if (rangerProjectileConfig.flipRelativePositionTowardCasterFacingDirection)
                {
                    relativePos = relativePos.FlipFollowDirection(caster.FacingDirection());
                }
                prefabPath       = rangerProjectileConfig.prefabPath;
                lifetimes        = rangerProjectileConfig.lifetimes;
                trajectoryConfig = rangerProjectileConfig.trajectoryConfig;
                hitBoxes.Add(rangerProjectileConfig.hitBox);
                targetLockingDuration = rangerProjectileConfig.lockDuration;
                targetLockingEventId  = rangerProjectileConfig.lockEid;
                targetLockingClampY   = rangerProjectileConfig.clampY;
                break;

            default:
                DLog.LogError(string.Format(
                                  "Cannot create projectile of type '{0}'", projectileType
                                  ));
                break;
            }

            Vector2 worldPos = pivotPosition + relativePos;

            args.SetEntry(TemplateArgsName.Position, worldPos);
            args.SetEntry(TemplateArgsName.EntityType, EntityType.Projectile);
            args.SetEntry(TemplateArgsName.Group, caster.Group());
            args.SetEntry(TemplateArgsName.Projectile_PrefabPath, prefabPath);
            args.SetEntry(TemplateArgsName.Projectile_ParentCharacter, caster);
            args.SetEntry(TemplateArgsName.Projectile_ParentSkill, parentSkill);
            args.SetEntry(TemplateArgsName.Projectile_HitBoxes, hitBoxes);
            args.SetEntry(
                TemplateArgsName.Projectile_ParentEntity_TimeScaleComponent,
                casterEntity.GetComponent <TimeScaleComponent>()
                );
            args.SetEntry(TemplateArgsName.Projectile_Lifetime, lifetimes);
            args.SetEntry(TemplateArgsName.Projectile_Trajectory, trajectoryConfig);
            args.SetEntry(TemplateArgsName.Projectile_DamageTicker, damageTickerConfig);
            args.SetEntry(TemplateArgsName.Projectile_Blockable, cpa.projectile.blockable);
            args.SetEntry(TemplateArgsName.Projectile_BlockDirection, BlockDirection.Front);
            args.SetEntry(TemplateArgsName.Projectile_BlockSource, Source.PlainValue);
            args.SetEntry(TemplateArgsName.Projectile_BlockCount, 0);
            args.SetEntry(TemplateArgsName.Projectile_BlockDirection, BlockDirection.Front);
            args.SetEntry(TemplateArgsName.Projectile_UsageGoal, usageGoal);
            args.SetEntry(TemplateArgsName.MapColliderBoundaries, mapColliders);
            args.SetEntry(TemplateArgsName.Projectile_CollisionEvaluator, projectileConfig.ShowCollisionGroupEvaluator());
            args.SetEntry(TemplateArgsName.Projectile_SleepTime, cpa.projectile.sleep);
            args.SetEntry(TemplateArgsName.Projectile_TargetLockingDuration, targetLockingDuration);
            args.SetEntry(TemplateArgsName.Projectile_TargetLockingEventId, targetLockingEventId);
            args.SetEntry(TemplateArgsName.Projectile_TargetLockingClampY, targetLockingClampY);
            args.SetEntry(TemplateArgsName.Projectile_PivotCharacter, caster);
            args.SetEntry(TemplateArgsName.Projectile_Environment, environment);
            if (preferedArgs != null)
            {
                if (preferedArgs.Contains(TemplateArgsName.Position))
                {
                    pivotPosition = preferedArgs.GetEntry <Vector2>(TemplateArgsName.Position);
                    worldPos      = pivotPosition + relativePos;
                    args.SetEntry(TemplateArgsName.Position, worldPos);
                }

                if (preferedArgs.Contains(TemplateArgsName.Projectile_BlockDirection))
                {
                    args.SetEntry(
                        TemplateArgsName.Projectile_BlockDirection,
                        preferedArgs.GetEntry <BlockDirection>(TemplateArgsName.Projectile_BlockDirection)
                        );
                }

                if (preferedArgs.Contains(TemplateArgsName.Projectile_BlockSource))
                {
                    args.SetEntry(
                        TemplateArgsName.Projectile_BlockSource,
                        preferedArgs.GetEntry <Source>(TemplateArgsName.Projectile_BlockSource)
                        );
                }

                if (preferedArgs.Contains(TemplateArgsName.Projectile_BlockCount))
                {
                    args.SetEntry(
                        TemplateArgsName.Projectile_BlockCount,
                        preferedArgs.GetEntry <int>(TemplateArgsName.Projectile_BlockCount)
                        );
                }

                if (preferedArgs.Contains(TemplateArgsName.Projectile_PivotCharacter))
                {
                    args.SetEntry(
                        TemplateArgsName.Projectile_PivotCharacter,
                        preferedArgs.GetEntry <Character>(TemplateArgsName.Projectile_PivotCharacter)
                        );
                }
            }
            projectileEntity = promiseWorld.CreateEntity(null, TemplateName.Projectile, args);
            creationPromise  = projectileEntity.GetComponent <EntityCreationPromiseComponent>().Promise;
            creationPromise.Then(entity => { CheckIfProjectileGameObjectIsInstantiated(caster, parentSkill, entity); });

            return(new SsarTuple <Entity, IPromise <Entity> >(projectileEntity, creationPromise));
        }
コード例 #22
0
        public Loopable Produce(Character caster, Skill skill, SkillId skillId, BaseEvent baseEvent,
                                SkillCastingSource skillCastingSource, TemplateArgs args)
        {
            BaseAction ba         = baseEvent.ShowAction();
            ActionType actionType = ba.ShowActionType();
            Loopable   loopable   = null;

            switch (actionType)
            {
            case ActionType.Camera:
                CameraAction        ca     = (CameraAction)ba;
                CameraAction.BaseFx bf     = ca.fx;
                CameraAction.FxType fxType = bf.ShowFxType();
                switch (fxType)
                {
                case CameraAction.FxType.Shake:
                    CameraAction.ShakeFx sf = (CameraAction.ShakeFx)bf;
                    loopable = new CameraShake(environment, sf);
                    break;

                case CameraAction.FxType.Fade:
                    loopable = new CameraFade(environment, baseEvent);
                    break;

                case CameraAction.FxType.CinematicZoomToSelf:
                    loopable = new CameraCinematicZoomToSelf(environment, baseEvent, caster);
                    break;

                case CameraAction.FxType.SlowMotion:
                    loopable = new CameraSlowMotion(environment, baseEvent);
                    break;

                case CameraAction.FxType.AddTarget:
                    loopable = new CameraAddTarget(environment, baseEvent, caster);
                    break;

                default:
                    throw new Exception("Missing logic to handle camera fx of type " + fxType);
                }
                break;

            case ActionType.Dash:
                Dash dash = new Dash(baseEvent, caster, skill.IgnoreMinSpeedOnAirForDashes(), skill, environment);
                loopable = dash;
                break;

            case ActionType.Jump:
                bool jumpOverDistance = true;
                if (args != null)
                {
                    bool found;
                    jumpOverDistance = args.TryGetEntry <bool>(TemplateArgsName.JumpSkill_JumpOverDistance, out found);
                    if (!found)
                    {
                        jumpOverDistance = true;
                    }
                }
                Jump jump = new Jump(baseEvent, caster, skill, environment, jumpOverDistance);
                loopable = jump;
                break;

            case ActionType.Vfx:
                Vfxs.Vfx vfx = new Vfxs.Vfx(
                    baseEvent, environment, caster, skillCastingSource, skill, args
                    );
                loopable = vfx;
                break;

            case ActionType.Modifier:
                ModifierAction     ma       = (ModifierAction)ba;
                BaseModifierConfig bmc      = ma.modifierConfig;
                ModifierInfo       mi       = modifierInfoFactory.CreateFrom(skill, bmc, environment);
                EntityReference    er       = caster.GameObject().GetComponent <EntityReference>();
                Modifier           modifier = DamageSystem.Instance.CreateModifier(
                    mi, er.Entity, er.Entity, caster.Position(),
                    caster.Position(), skill, skillId, 0
                    );
                if (modifier != null)
                {
                    caster.AddModifier(modifier);
                }
                loopable = new ModifierLoopable(modifier);
                break;

            case ActionType.Animation:
                loopable = new AnimationPlayback(baseEvent, caster);
                break;

            case ActionType.Teleport:
                TeleportAction          ta   = (TeleportAction)baseEvent.action;
                TeleportAction.ModeName mode = ta.mode.ShowModeName();
                switch (mode)
                {
                case TeleportAction.ModeName.PredefinedPositionOnMap:
                    new Teleport(baseEvent, caster, environment);
                    loopable = new ImmediatelyFinishedLoopable();
                    break;

                case TeleportAction.ModeName.KeepDistance:
                    TeleportAction.KeepDistanceMode kdm = (TeleportAction.KeepDistanceMode)ta.mode;
                    loopable = new TeleportKeepDistanceLogic(kdm, skill, environment, caster);
                    break;

                case TeleportAction.ModeName.AroundTarget:
                    TeleportAction.AroundTargetMode atm = (TeleportAction.AroundTargetMode)ta.mode;
                    loopable = new TeleportAroundTargetLogic(atm, caster, environment, skill);
                    break;

                case TeleportAction.ModeName.AroundTeamMate:
                    TeleportAction.AroundTeamMateMode atmm = (TeleportAction.AroundTeamMateMode)ta.mode;
                    loopable = new TeleportAroundTeamMate(atmm, caster, environment, skill);
                    break;

                default:
                    throw new Exception("Cannot create teleport of type " + mode);
                }
                break;

            case ActionType.FacingDirection:
                loopable = new FacingDirection(baseEvent, caster, environment);
                break;

            case ActionType.DashTowardTarget:
                DashTowardTarget dtt = new DashTowardTarget(baseEvent, caster, environment);
                loopable = dtt;
                break;

            case ActionType.JumpTowardTarget:
                loopable = new JumpTowardTarget(baseEvent, caster, environment);
                break;

            case ActionType.SpawnCharacter:
                SpawnCharacterAction sca = (SpawnCharacterAction)ba;
                loopable = new SpawnCharacter(sca, entitySpawner, caster, args, environment, skillId, hamc);
                break;

            case ActionType.Rotation:
                loopable = new Rotation(baseEvent, caster, environment);
                break;

            case ActionType.Timer:
                loopable = new Timer(baseEvent, skill);
                break;

            case ActionType.Sound:
                loopable = new AudioClipPlayback(baseEvent, environment);
                break;

            case ActionType.PassiveSkillOnOff:
                loopable = new PassiveSkillOnOff(baseEvent, caster);
                break;

            case ActionType.DistanceTracker:
                loopable = new DistanceTracker(baseEvent, skill, caster);
                break;

            case ActionType.SelfDamageDealing:
                loopable = new SelfDamageDealing(baseEvent, caster, skill, skillId);
                break;

            case ActionType.SwitchPhase:
                loopable = new SwitchPhase(skill);
                break;

            case ActionType.Movable:
                Entity        casterEntity  = caster.GameObject().GetComponent <EntityReference>().Entity;
                UserInput     userInput     = casterEntity.GetComponent <HeroStateMachineComponent>().UserInput;
                MovableAction movableAction = (MovableAction)ba;
                loopable = new Movable(movableAction, skill, caster.FacingDirection(), userInput, caster);
                break;

            case ActionType.Input:
                casterEntity = caster.GameObject().GetComponent <EntityReference>().Entity;
                userInput    = casterEntity.GetComponent <HeroStateMachineComponent>().UserInput;
                InputAction ia = (InputAction)ba;
                loopable = new InputSimulation(ia, (DefaultUserInput)userInput);
                break;

#if UNITY_EDITOR
            case ActionType.Macro:
                loopable = new Macro(baseEvent, caster);
                break;
#endif
            default:
                DLog.Log("Missing logic to handle action of type " + actionType);
                break;
            }

            return(loopable);
        }