Пример #1
0
    // Start is called before the first frame update
    void Awake()
    {
        damage       = enemyPreset.damage;
        moveTime     = enemyPreset.moveTime;
        idleTimeMin  = enemyPreset.idleTimeMin;
        idleTimeMax  = enemyPreset.idleTimeMax;
        wanderRadius = enemyPreset.wanderRadius;

        home = transform.position;

        trigger = GetComponentInChildren <DetectPlayer>();

        trigger.GetComponent <SphereCollider>().radius = enemyPreset.detectionRadius;

        navMeshAgent = GetComponent <NavMeshAgent>();

        navMeshAgent.speed = enemyPreset.speed;

        fsm = new FSM("MeleeAI FSM");

        WanderState = fsm.AddState("WanderState");
        IdleState   = fsm.AddState("IdleState");
        AlertState  = fsm.AddState("AlertState");
        MeleeState  = fsm.AddState("MeleeState");

        WanderAction = new WanderAction(WanderState);
        IdleAction   = new TextAction(IdleState);
        alertAction  = new AlertAction(AlertState);
        meleeAction  = new MeleeAction(MeleeState);

        WanderState.AddAction(WanderAction);
        IdleState.AddAction(IdleAction);
        AlertState.AddAction(alertAction);
        MeleeState.AddAction(meleeAction);

        WanderState.AddTransition("ToIdle", IdleState);
        WanderState.AddTransition("PlayerDetect", AlertState);
        IdleState.AddTransition("ToWander", WanderState);
        IdleState.AddTransition("PlayerDetect", AlertState);

        AlertState.AddTransition("ToIdle", IdleState);
        AlertState.AddTransition("ToMelee", MeleeState);
        MeleeState.AddTransition("ToAlert", AlertState);

        WanderAction.Init(this.transform, home, navMeshAgent, wanderRadius, moveTime, "ToIdle");
        IdleAction.Init("Idling", Random.Range(idleTimeMin, idleTimeMax), "ToWander");

        alertAction.Init(trigger, navMeshAgent, "ToIdle");
        meleeAction.Init(this.transform, damage, trigger, FindObjectOfType <PlayerManager>(), "ToAlert");

        fsm.Start("IdleState");
    }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        public static void createMeleeAction(Vector2 position, Vector2 heading, Transform transform, Entity owner)
        {
            Entity e = ecs_instance.create();

            Sprite sprite = new Sprite("sword", "swordnormal", 32, 32, 0, 0);

            MeleeAction action = new MeleeAction();

            action.Animation  = new SpriteAnimation(9, 20);
            action.ArcDegrees = 180;
            action.Owner      = owner;
            action.Lifetime   = 250;
            action.Range      = 32;

            ecs_instance.add_component(e, new Position(position, new Vector2(16)));
            ecs_instance.add_component(e, new Heading(heading));
            ecs_instance.add_component(e, transform);
            ecs_instance.add_component(e, sprite);
            ecs_instance.add_component(e, action);

            ecs_instance.resolve(e);
        }
Пример #3
0
        protected override void process(Entity entity)
        {
            MeleeAction      action   = (MeleeAction)m_MeleeActionMapper.get(entity);
            Position         position = (Position)m_PositionMapper.get(entity);
            SpatialPartition spatial  = (SpatialPartition)m_SpatialMapper.get(m_Spatial);

            action.ElapsedTime += ecs_instance.ElapsedTime;

            //is it time for the melee action to die?
            if (action.ElapsedTime >= action.Lifetime)
            {
                ecs_instance.delete_entity(entity);
                return;
            }

            //retrieve all local entities
            //List<Entity> locals = spatial.QuadTree.retrieveContentsAtLocation(position.Pos);
            List <Entity> locals = spatial.QuadTree.findAllWithinRange(position.Pos, action.Range);

            //is the location good?
            if (locals != null)
            {
                //is there anyone here?
                if (locals.Count > 0)
                {
                    for (int i = 0; i < locals.Count; i++)
                    {
                        //dont attempt to melee owner
                        if (locals[i] == action.Owner)
                        {
                            continue;
                        }

                        if (action.HitByAction.Contains(locals[i]))
                        {
                            continue;
                        }

                        Life life = (Life)m_LifeMapper.get(locals[i]);

                        //if no life, dont bother
                        if (life == null)
                        {
                            continue;
                        }

                        //if not alive, dont bother
                        if (!life.IsAlive)
                        {
                            continue;
                        }

                        //interaction available?
                        Interactable interactions = (Interactable)m_InteractionMapper.get(locals[i]);
                        if (interactions != null)
                        {
                            Position lPosition = (Position)m_PositionMapper.get(locals[i]);

                            Position oPosition = (Position)m_PositionMapper.get(action.Owner);
                            Vector2  lToO      = (oPosition.Pos + oPosition.Offset) - (lPosition.Pos + lPosition.Offset); //local to owner
                            Heading  head      = (Heading)m_HeadingMapper.get(entity);                                    //get the weapon heading
                            bool     facing    = (Vector2.Dot(head.getHeading(), lToO) < 0);                              //is the weapon facing the local?

                            //if you're facing, are you within range?
                            if (facing && (Vector2.Distance(lPosition.Pos + lPosition.Offset, position.Pos + position.Offset) <= action.Range))
                            {
                                //does it support this interaction?
                                if (interactions.SupportedInteractions.MELEE_ACTIONABLE &&
                                    interactions.SupportedInteractions.ATTACKABLE)
                                {
                                    Factions lfactions = (Factions)m_FactionMapper.get(locals[i]);
                                    Factions pfactions = (Factions)m_FactionMapper.get(action.Owner);

                                    //dont attack allies
                                    if (lfactions.OwnerFaction.FactionType == pfactions.OwnerFaction.FactionType)
                                    {
                                        continue;
                                    }

                                    //add to hit-list so we dont attack it again on swing follow-through
                                    action.HitByAction.Add(locals[i]);

                                    //create melee attack
                                    UtilFactory.createAttack(action.Owner, locals[i], AttackType.Melee);

                                    //destroy melee action
                                    //ecs_instance.delete_entity(entity);
                                    //return;
                                }
                            }
                        }
                    }
                }
            }

            //get info for rotation update
            Heading   heading   = (Heading)m_HeadingMapper.get(entity);
            Transform transform = (Transform)m_TransformMapper.get(entity);

            //rotate melee by degrees over the melee arc
            float rot = (((float)action.Animation.updateFrame(ecs_instance.ElapsedTime) / (float)action.Animation.Frames) * action.ArcDegrees) - (action.ArcDegrees / 2f);

            transform.Rotation = rot * (((float)Math.PI) / 180f) - VectorHelper.getAngle(new Vector2(1, 0), heading.getHeading());

            //adjust the arc based on current position (i.e., move with the player)
            Position ownerPos = (Position)m_PositionMapper.get(action.Owner);
            Vector2  pos      = ownerPos.Pos + new Vector2(16, 0);// +ownerPos.getOffset();
            Vector2  dir      = heading.getHeading();

            dir.Normalize();
            position.Pos = pos + dir * 10;
        }
Пример #4
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="processingAction"></param>
    /// <param name="targets"></param>
    /// <param name="user"></param>
    private void processMeleeAction(MeleeAction processingAction,
                                    List <System.Object> targets,
                                    ParentPuppetScript user)
    {
        Debug.LogError("The Hunter " + user.getPuppetName() +
                       " is using the action " + ((BattleAction)processingAction).name +
                       " on the following targets:");

        foreach (System.Object target in targets)
        {
            Debug.LogError(((MonsterBodyPart)target).name);
        }

        int strengthModifier = processingAction.
                               getStrengthModifierValue();

        int strength = modifyValue(user.getModifiedStrength(), strengthModifier,
                                   processingAction.getStrengthModifierType());

        float chanceToHit = processingAction.getChanceToHit();

        int piercing = processingAction.getPiercing();

        int damage = processingAction.getDamagae();

        int meleeHitCount = user.getModifiedMeleeAttackCount();

        for (int i = 0; i < targets.Count; i++)
        {
            for (int hits = 0; hits < meleeHitCount; hits++)
            {
                switch (targets[i])
                {
                case MonsterBodyPart monsterBodyPart:

                    Debug.LogError("The target is a monster bodypart");

                    Debug.LogError("Chance to hit is " + chanceToHit);

                    // If the chance to hit succes, proceed, otherwise end this
                    if (Random.Range(0, 99) < chanceToHit)
                    {
                        Debug.LogError("HIT!");

                        // Remove some toughness from the monster through
                        //   the peircing value
                        float monsterToughness = monsterBodyPart.toughness - piercing;

                        // Clamp the monster toughness so that it is always
                        // greater than 0 (such that we do not divide by zero)
                        monsterToughness = Mathf.Clamp(monsterToughness, 1.0f,
                                                       float.PositiveInfinity);

                        // Get the chance to penetrate
                        float chanceToPierce = user.getModifiedStrength() /
                                               (monsterToughness * 2);

                        Debug.LogError("The chance to pierce is: " + user.getModifiedStrength() + " / ((" + monsterBodyPart.toughness + " - " + piercing + ") * 2) = " + chanceToPierce);

                        // If it pens, then deal damag based on the given amount
                        if (Random.Range(0, 99) < (float)(chanceToPierce * 100f))
                        {
                            Debug.LogError("PIERCE!");

                            Debug.LogError("Bodypart HP is " + monsterBodyPart.hp + " and damage is " + damage);

                            monsterBodyPart.damageBodyPart(damage);

                            Debug.LogError("Bodypart HP after damage is " + monsterBodyPart.hp);
                        }
                        else
                        {
                            Debug.LogError("DEFLECTED!");
                            // Tell user the hit reflected
                        }
                    }
                    else
                    {
                        Debug.LogError("MISS!");
                        // Tell user they missed
                    }
                    break;

                default:
                    Debug.LogError("Error! unknown action target from the" +
                                   "current processing target: " +
                                   targets[i].ToString());
                    break;
                }
            }
        }
    }