Inheritance: MonoBehaviour
Beispiel #1
0
    public void Remove(AI_Character oldVillager)
    {
        if (villagerList.Contains(oldVillager))
        {
            villagerList.Remove(oldVillager);
            totalVillagers--;
            switch (oldVillager.myRole)
            {
            case AI_Character.Role.Villager:
                villagers--;
                break;

            case AI_Character.Role.Woodcutter:
                woodcutters--;
                break;

            case AI_Character.Role.Miner:
                miners--;
                break;

            case AI_Character.Role.Militia:
                militia--;
                break;

            default:
                break;
            }
        }
        else
        {
            Debug.Log("Tried to remove non-existing villager");
        }
    }
Beispiel #2
0
    /// <summary>
    /// Used by any character to find a path to a building target
    /// </summary>
    /// <returns>The building.</returns>
    /// <param name="character">Character.</param>
    /// <param name="buildingType">Building type.</param>
    public Building FindBuilding(AI_Character character, Building.Structure buildingType)
    {
        int         num  = -1;
        float       dist = 9999;
        NavMeshPath path = new NavMeshPath();

        for (int i = 0; i < buildingsList.Count; i++)
        {
            if (buildingsList [i].structure != buildingType)
            {
                continue;
            }

            if (!Distance.GetPath(character.transform.position, buildingsList [i].buildingTarget.transform.position, NavMesh.AllAreas, path))
            {
                continue;
            }
            else
            {
                if (Distance.GetPathLength(path) < dist)
                {
                    dist = Distance.GetPathLength(path);
                    num  = i;
                }
            }
        }

        if (num == -1)
        {
            return(null);
        }
        return(buildingsList [num]);
    }
Beispiel #3
0
    public EnemyCharacter FindClosestEnemy(AI_Character character, float detectionRange)
    {
        int   num  = -1;
        float dist = detectionRange + 0.1f;

        NavMeshPath path = new NavMeshPath();

        for (int i = 0; i < enemyList.Count; i++)
        {
            if (!Distance.GetPath(character.transform.position, enemyList [i].transform.position, NavMesh.AllAreas, path))
            {
                break;
            }
            else
            {
                if (Distance.GetPathLength(path) < dist)
                {
                    dist = Distance.GetPathLength(path);
                    num  = i;
                }
            }
        }

        if (num == -1)
        {
            return(null);
        }

        return(enemyList [num]);
    }
 // Character dealt damage
 public void OnDamageDealt(AI_Character target, float damage_dealt)
 {
     if (this.CurrentAction != null)
     {
         this.CurrentAction.OnActionDamageDealt(damage_dealt);
     }
 }
 // Character took damage
 public void OnDamageTaken(AI_Character caster, float damage_taken)
 {
     if (this.CurrentAction != null)
     {
         this.CurrentAction.OnActionDamageTaken(damage_taken);
     }
 }
Beispiel #6
0
    /// <summary>
    /// Called when a character finishes its current action.
    /// </summary>
    /// <param name="caster">Caster</param>
    public void OnCharacterActionFinished(AI_Character caster)
    {
        Debug.Log("[AI] Action finished (Caster ID: " + caster.CharacterID + ").");
        AI_Action action = caster.OnActionFinished(this.LastUpdateTime);

        this.TrainAction(action);
    }
 public AI_Action(EActionCode action_code, AI_Character caster, AI_Character target)
 {
     this.ActionCode = action_code;
     this.Caster     = caster;
     this.Target     = target;
     this.Success    = false;
 }
Beispiel #8
0
    public void CheckLook()
    {
        UIManager.instance.HideTargetText();
        UIManager.instance.HideCenterText();
        UIManager.instance.HideHealthBar();

        Ray        ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward);
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, 4.0f))
        {
            if (hit.transform.tag == "Resource")
            {
                Resource resource = hit.transform.GetComponent <Resource> ();
                UIManager.instance.UpdateHealthBar(resource.amount, resource.maxAmount, hit.transform.name);

                if (hitCount < maxHitCount)
                {
                    if (resource.resourceType == Resource.ResourceType.Wood)
                    {
                        UIManager.instance.ShowCenterText("Press LMB with the AXE to collect");
                    }
                    else
                    {
                        UIManager.instance.ShowCenterText("Press LMB with the PICKAXE to collect");
                    }
                }
                else
                {
                    UIManager.instance.ShowCenterText("Can't carry anymore!");
                }
            }
            if (hit.transform.tag == "ResourceDrop" &&
                hit.transform.root.gameObject.GetComponent <Building> ().structure == Building.Structure.ResourceDrop &&
                myItem != Resource.ResourceType.None)
            {
                UIManager.instance.ShowCenterText("Press 'G' to drop off resources!");
            }
            if (hit.transform.tag == "Building")
            {
                Building currentBuilding = hit.transform.root.gameObject.GetComponent <Building> ();
                UIManager.instance.ShowFlavourText(currentBuilding);
            }
            if (hit.transform.root.tag == "Ally")
            {
                AI_Character ally = hit.transform.root.gameObject.GetComponent <AI_Character> ();
                UIManager.instance.UpdateHealthBar(ally.health, ally.maxHealth, ally.transform.name);
            }
            if (hit.transform.root.tag == "Enemy")
            {
                EnemyCharacter enemy = hit.transform.root.gameObject.GetComponent <EnemyCharacter> ();
                UIManager.instance.UpdateHealthBar(enemy.health, enemy.maxHealth, enemy.transform.name);
            }
        }
        else
        {
            //not seeing anything
        }
    }
 public static void DecreaseRole(AI_Character.Role removingRole)
 {
     if (CheckVillagerInRole(removingRole))
     {
         AI_Character chosenVillager = GetVillagerInRole(removingRole);
         UpdateRoleCount(chosenVillager.myRole, AI_Character.Role.Villager);
         chosenVillager.SetRole(AI_Character.Role.Villager);
     }
 }
 public static void IncreaseRole(AI_Character.Role newRole)
 {
     if (CheckAvailableVillager())
     {
         AI_Character chosenVillager = GetAvailableVillager();
         UpdateRoleCount(chosenVillager.myRole, newRole);
         chosenVillager.SetRole(newRole);
     }
 }
Beispiel #11
0
 public void Add(AI_Character newVillager)
 {
     if (villagerList.Contains(newVillager))
     {
         return;
     }
     villagerList.Add(newVillager);
     villagers++;
     totalVillagers++;
 }
Beispiel #12
0
    /// <summary>
    /// Update all characters.
    /// </summary>
    /// <param name="p">Update parameters</param>
    public void UpdateCharacters(AI_Params p)
    {
        foreach (AI_Params.AI_ParamCharacter c in p.Characters)
        {
            // Create a new character if ID doesn't already exist
            if (!this.Characters.ContainsKey(c.CharacterID))
            {
                Debug.Log("Adding new character (Character ID: " + c.CharacterID + ").");
                this.Characters[c.CharacterID] = new AI_Character(c.CharacterID, c.CharacterType);
            }

            // Update character information
            AI_Character character = this.Characters[c.CharacterID];
            character.OnSeenByAI(this.LastUpdateTime, c.Position, c.Direction, c.Velocity);
        }
    }
Beispiel #13
0
    /// <summary>
    /// Trains the anticipation network.
    /// </summary>
    /// <param name="player">Player</param>
    /// <param name="action_code">Code of the action performed</param>
    public void TrainAnticipation(AI_Character player, EActionCode action_code)
    {
        AI_DeepLearningNetwork network;

        float[] outputs = new float[(int)EActionCode.Count];
        for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
        {
            outputs[(int)code] = (code == action_code) ? 1.0f : 0.0f;
        }

        foreach (AI_Character c in this.Characters.Values)
        {
            if (c.CharacterType == ECharacterType.CharacterTypeEnemy && c.IsAlive)
            {
                if (player.PreviousAction != null)
                {
                    network = this.Networks_Anticipation_1[player.PreviousAction.ActionCode];
                    network.Learn(new float[] {
                        Vector3.Distance(c.Position, player.Position),
                        Vector3.Angle(player.Direction, c.Position - player.Position),
                        Vector3.Angle(c.Direction, player.Position - c.Position),
                        this.LastUpdateTime - player.PreviousAction.CastTime
                    }, outputs);
                }
                if (c.CurrentAction != null)
                {
                    network = this.Networks_Anticipation_2[c.CurrentAction.ActionCode];
                    network.Learn(new float[] {
                        Vector3.Distance(c.Position, player.Position),
                        Vector3.Angle(player.Direction, c.Position - player.Position),
                        Vector3.Angle(c.Direction, player.Position - c.Position),
                        this.LastUpdateTime - c.CurrentAction.CastTime
                    }, outputs);
                }
                else
                {
                    network = this.Networks_Anticipation_2[EActionCode.ActionCodeNoAction];
                    network.Learn(new float[] {
                        Vector3.Distance(c.Position, player.Position),
                        Vector3.Angle(player.Direction, c.Position - player.Position),
                        Vector3.Angle(c.Direction, player.Position - c.Position),
                        this.LastUpdateTime - c.CurrentAction.CastTime
                    }, outputs);
                }
            }
        }
    }
Beispiel #14
0
    /// <summary>
    /// Called when a character starts a new action.
    /// </summary>
    /// <param name="caster">Caster</param>
    /// <param name="action_code">Code of the action (see EActionCode)</param>
    public void OnCharacterActionStarted(AI_Character caster, EActionCode action_code)
    {
        Debug.Log("[AI] Action started (Caster ID: " + caster.CharacterID + ", Action Code: " + action_code + ").");
        AI_Character target = null;

        // Determining the target
        switch (caster.CharacterType)
        {
        case ECharacterType.CharacterTypeEnemy:
            Debug.Assert(this.Characters.ContainsKey(AI_Params.PlayerID), "[AI] Invalid player ID (" + AI_Params.PlayerID + ").");
            target = this.Characters[AI_Params.PlayerID];
            break;

        case ECharacterType.CharacterTypePlayer:
            float distance = 10000.0f;
            foreach (AI_Character c in this.Characters.Values)
            {
                if (distance > Vector3.Distance(c.Position, caster.Position) + Mathf.Abs(Vector3.Angle(caster.Direction, c.Position - caster.Position)))
                {
                    distance = Vector3.Distance(c.Position, caster.Position) + Mathf.Abs(Vector3.Angle(caster.Direction, c.Position - caster.Position));
                    target   = c;
                }
            }
            break;
        }

        // Registering the action
        AI_Action action = caster.OnActionStarted(this.LastUpdateTime, action_code, target);

        foreach (AI_Character c in this.Characters.Values)
        {
            if ((c.CurrentAction != null) && (c.CurrentAction.Target.CharacterID == caster.CharacterID))
            {
                c.CurrentAction.OnTargetActionStarted(action);
            }
        }

        // Training anticipation network
        if (caster.CharacterType == ECharacterType.CharacterTypePlayer)
        {
            this.TrainAnticipation(caster, action_code);
        }
    }
Beispiel #15
0
    /// <summary>
    /// used specifically for dropping off resources at the correcct building
    /// </summary>
    /// <returns>The building resource drop.</returns>
    /// <param name="character">Character requesting path.</param>
    /// <param name="buildingType">Building type.</param>
    /// <param name="resourceType">Resource type.</param>
    public Building FindBuildingResourceDrop(AI_Character character, Building.Structure buildingType, Resource.ResourceType resourceType)
    {
        int         num  = -1;
        float       dist = 9999;
        NavMeshPath path = new NavMeshPath();

        for (int i = 0; i < buildingsList.Count; i++)
        {
            //check for right structure
            if (buildingsList [i].structure != buildingType)
            {
                continue;
            }


            //check for right drop type
            if (buildingsList [i].dropType != Building.ResourceDropType.All && buildingsList [i].dropType.ToString() != resourceType.ToString())
            {
                continue;
            }


            if (!Distance.GetPath(character.transform.position, buildingsList [i].buildingTarget.transform.position, NavMesh.AllAreas, path))
            {
                continue;
            }
            else
            {
                if (Distance.GetPathLength(path) < dist)
                {
                    dist = Distance.GetPathLength(path);
                    num  = i;
                }
            }
        }

        if (num == -1)
        {
            return(null);
        }
        return(buildingsList [num]);
    }
Beispiel #16
0
    // Update is called once per frame
    void Update()
    {
        #region Check for AI Follow Link
        if (OtherAI_Object == null)
        {
            if (this.gameObject.name != "AI Matt" && GameObject.Find("AI Matt") != null)
            {
                if (GameObject.Find("AI Matt").GetComponent<AI_Character>().Action == AI_Action.FollowPlayer)
                    OtherAI_Object = GameObject.Find("AI Matt");
            }
            if (this.gameObject.name != "AI Josh" && GameObject.Find("AI Josh") != null)
            {
                if (GameObject.Find("AI Josh").GetComponent<AI_Character>().Action == AI_Action.FollowPlayer)
                    OtherAI_Object = GameObject.Find("AI Josh");
            }
            if (this.gameObject.name != "AI Kate" && GameObject.Find("AI Kate") != null)
            {
                if (GameObject.Find("AI Kate").GetComponent<AI_Character>().Action == AI_Action.FollowPlayer)
                    OtherAI_Object = GameObject.Find("AI Kate");
            }
            if (this.gameObject.name != "AI April" && GameObject.Find("AI April") != null)
            {
                if (GameObject.Find("AI April").GetComponent<AI_Character>().Action == AI_Action.FollowPlayer)
                    OtherAI_Object = GameObject.Find("AI April");
            }
            if (this.gameObject.name != "AI Ethan" && GameObject.Find("AI Ethan") != null)
            {
                if (GameObject.Find("AI Ethan").GetComponent<AI_Character>().Action == AI_Action.FollowPlayer)
                    OtherAI_Object = GameObject.Find("AI Ethan");
            }

            if (OtherAI_Object != null)
                Script_OtherAIObject = OtherAI_Object.GetComponent<AI_Character>();
        }
        #endregion

        //var
        CircleCollision.enabled = true;

        if (Action == AI_Action.Stationary) //Stay at complete rest
        {
            #region Completely Stationary

            Body.isKinematic = true;

            #endregion
        }
        else if (Action == AI_Action.StationaryWithDir) //Stay at rest, but occationaly change directions
        {
            #region Stationary With Direction

            Body.isKinematic = true;

            if (Random.Range(0, 150) == 69) //Choose random number from 1 - 150. If the number is 69, change directions
            {
                int DirectionRange = Random.Range(0, 4); //Randomly choose a direction: 0 is down, 1 is right, 2 is up, 3 is left

                if (DirectionRange == 0) //Look up AI!
                {
                    Anim.SetInteger("Direction", 0);
                }
                else if (DirectionRange == 1) //Look right AI!
                {
                    Anim.SetInteger("Direction", 1);
                }
                else if (DirectionRange == 2) //Look down AI!
                {
                    Anim.SetInteger("Direction", 2);
                }
                else if (DirectionRange == 3) //Look left AI!
                {
                    Anim.SetInteger("Direction", 3);
                }

            }

            #endregion
        }
        else if (Action == AI_Action.FollowPlayer) //Follow player
        {
            #region Follow Player

            #region SavePosition
            //Check if you need to write AI position to save data
            CounterPos++;
            if (CounterPos >= 150)
            {
                //Read in SaveGame.xml
                XmlDocument SaveGameDoc = new XmlDocument();
                SaveGameDoc.LoadXml(DoSaveGame.FetchSaveData());

                foreach (XmlNode node in SaveGameDoc.SelectNodes("SaveData/SaveState/Scenes/Scene"))
                {
                    if (Application.loadedLevelName == node.SelectSingleNode("SceneName").InnerText)
                    {
                        if (this.gameObject.name == "AI Josh")
                        {
                            node.SelectSingleNode("AI/JoshAI/X").InnerText = transform.position.x.ToString();
                            node.SelectSingleNode("AI/JoshAI/Y").InnerText = transform.position.y.ToString();
                            node.SelectSingleNode("AI/JoshAI/Action").InnerText = "FollowPlayer";
                        }
                        else if (this.gameObject.name == "AI Matt")
                        {
                            node.SelectSingleNode("AI/MattAI/X").InnerText = transform.position.x.ToString();
                            node.SelectSingleNode("AI/MattAI/Y").InnerText = transform.position.y.ToString();
                            node.SelectSingleNode("AI/MattAI/Action").InnerText = "FollowPlayer";
                        }
                        else if (this.gameObject.name == "AI Kate")
                        {
                            node.SelectSingleNode("AI/KateAI/X").InnerText = transform.position.x.ToString();
                            node.SelectSingleNode("AI/KateAI/Y").InnerText = transform.position.y.ToString();
                            node.SelectSingleNode("AI/KateAI/Action").InnerText = "FollowPlayer";
                        }
                        else if (this.gameObject.name == "AI April")
                        {
                            node.SelectSingleNode("AI/AprilAI/X").InnerText = transform.position.x.ToString();
                            node.SelectSingleNode("AI/AprilAI/Y").InnerText = transform.position.y.ToString();
                            node.SelectSingleNode("AI/AprilAI/Action").InnerText = "FollowPlayer";
                        }
                        else if (this.gameObject.name == "AI Ethan")
                        {
                            node.SelectSingleNode("AI/EthanAI/X").InnerText = transform.position.x.ToString();
                            node.SelectSingleNode("AI/EthanAI/Y").InnerText = transform.position.y.ToString();
                            node.SelectSingleNode("AI/EthanAI/Action").InnerText = "FollowPlayer";
                        }

                        //Save XML
                        DoSaveGame.UpdateSaveData(SaveGameDoc);
                    }
                }

                CounterPos = 0;
            }
            #endregion

            //Var for AI x and y
            float XMove = 0;
            float YMove = 0;

            Body.isKinematic = false;

            if (FindPath() > 1.75) //If AI far away from Player, go to the player
            {
                //if game just started and everything is set to 0 (and if everything is 0, it causes problems)
                if (PlayerPreviousPosition[0, 0] == 0 && PlayerPreviousPosition[0, 1] == 0 && AIarrayPart == 0)
                {
                    for (int i = 0; i < 120; i++) //fill entire array with players position (better than 0)
                    {
                        PlayerPreviousPosition[i, 0] = Player.Body.position.x;
                        PlayerPreviousPosition[i, 1] = Player.Body.position.y;
                    }
                }

                //find players position every 10 frames (1/6 a second). This is so it remembers the players path. (history path)
                if (PlayerPositionCounter >= 10)
                    {
                        if (ArrayCount >= 120) //Go to beginning of array
                        {
                            ArrayCount = 0;
                        }
                        PlayerPreviousPosition[ArrayCount, 0] = Player.Body.position.x;
                        PlayerPreviousPosition[ArrayCount, 1] = Player.Body.position.y;
                        ArrayCount++;

                        PlayerPositionCounter = 0;
                    }
                    PlayerPositionCounter++;

                //AI follow the history path of player

                //Follow to interval
                if (Counter7 >= 11) //Do not make is 11 or less!!!
                {
                    AIarrayPart++;
                    if (AIarrayPart >= 120)
                    {
                        AIarrayPart = 0;
                    }
                    Counter7 = 0;

                    //---Check if skip is needed---
                    //check 1 behind ai count to see if the (x,y) is the same, and if so, preform a skip (for a max skip length of one full period (120)
                    //special case of when array index is 0, it looks back at index 119

                    if (AIarrayPart == 0) //Special Case
                    {
                        //Look back in time
                        if (PlayerPreviousPosition[AIarrayPart, 0] == PlayerPreviousPosition[119, 0] && PlayerPreviousPosition[AIarrayPart, 1] == PlayerPreviousPosition[119, 1])
                        {
                            //If the same, do a skip
                            for (int i = 0; i < 120; i++)
                            {
                                AIarrayPart++; //Increment AIarrayPart counter
                                if (AIarrayPart >= 120) //Check if is at end of array so it can start from beginning. Kinda like a special case
                                {
                                    AIarrayPart = 0;
                                    if (ArrayCount == 119 || PlayerPreviousPosition[AIarrayPart, 0] != PlayerPreviousPosition[119, 0] || PlayerPreviousPosition[AIarrayPart, 1] != PlayerPreviousPosition[119, 1])
                                    {
                                        break; //Exit loop
                                    }
                                }
                                else //non-special case / regular case
                                {
                                    if (AIarrayPart == ArrayCount + 1 || PlayerPreviousPosition[AIarrayPart, 0] != PlayerPreviousPosition[AIarrayPart - 1, 0] || PlayerPreviousPosition[AIarrayPart, 1] != PlayerPreviousPosition[AIarrayPart - 1, 1])
                                    {
                                        break; //Exit loop
                                    }
                                }
                            }
                        }
                    }
                    else //Regular Case
                    {
                        //Look back in time
                        if (PlayerPreviousPosition[AIarrayPart, 0] == PlayerPreviousPosition[AIarrayPart - 1, 0] && PlayerPreviousPosition[AIarrayPart, 1] == PlayerPreviousPosition[AIarrayPart - 1, 1])
                        {
                            //If the same, do a skip
                            for (int i = 0; i < 120; i++)
                            {
                                AIarrayPart++; //Increment AIarrayPart counter
                                if (AIarrayPart >= 120) //Check if is at end of array so it can start from beginning. Kinda like a special case
                                {
                                    AIarrayPart = 0;
                                    if (ArrayCount == 119 || PlayerPreviousPosition[AIarrayPart, 0] != PlayerPreviousPosition[119, 0] || PlayerPreviousPosition[AIarrayPart, 1] != PlayerPreviousPosition[119, 1])
                                    {
                                        break; //Exit loop
                                    }
                                }
                                else //non-special case / regular case
                                {
                                    if (AIarrayPart == ArrayCount + 1 || PlayerPreviousPosition[AIarrayPart, 0] != PlayerPreviousPosition[AIarrayPart - 1, 0] || PlayerPreviousPosition[AIarrayPart, 1] != PlayerPreviousPosition[AIarrayPart - 1, 1])
                                    {
                                        break; //Exit loop
                                    }
                                }
                            }
                        }
                    }

                }
                Counter7++;

                    if (Body.position.x != PlayerPreviousPosition[AIarrayPart, 0])
                    {
                        XMove = Find_X_Distance();
                    }

                    if (Body.position.y != PlayerPreviousPosition[AIarrayPart, 1])
                    {
                        YMove = Find_Y_Distance();
                    }

            }
            else if (FindPath() < 1.75) //If Player and AI collide
            {
                //Let Player go through AI, temporarily disable circle collider
                //(gameObject.GetComponent(typeof(Collider)) as Collider).isTrigger = true;
                CircleCollision.enabled = false;

                if (FollowOtherAI == true && Script_OtherAIObject.FindPath() > 1.75)
                {
                    //Do Nothing
                }
                else
                {
                    //Reset PreviousPlayerPosition Array
                    AIarrayPart = 0;
                    for (int i = 0; i < 120; i++)
                    {
                        PlayerPreviousPosition[i, 0] = Player.Body.position.x;
                        PlayerPreviousPosition[i, 1] = Player.Body.position.y;
                    }
                }

            }

            //Execute Movement
            PlayerMovement.PlayerMove(Body, WalkSpeed, Anim, XMove, YMove);

            #endregion
        }
        else if (Action == AI_Action.Event) //Do an event
        {
            #region Preform Event

            Body.isKinematic = true;

            if (EventType == PreviousEventType) //Continue on with event
            {
                EventStepCase = Body.GetComponent<AI_Events>().PreformEvent(Body, WalkSpeed, Anim, EventType, Original_X, Original_Y, EventStepCase); //Execute Event while retrieving the CaseStep
            }
            else //Start a new event
            {
                Original_X = Body.position.x;
                Original_Y = Body.position.y;
                EventStepCase = 1;

                PreviousEventType = EventType;

                Body.GetComponent<AI_Events>().GetLocation(Body, EventType, EventStepCase);

                //---Set values for save data---
                //Read in SaveGame.xml
                XmlDocument SaveGameDoc = new XmlDocument();
                SaveGameDoc.LoadXml(DoSaveGame.FetchSaveData());

                //Find current scene then find ScenePart.
                foreach (XmlNode node in SaveGameDoc.SelectNodes("SaveData/SaveState/Scenes/Scene"))
                {
                    if (Application.loadedLevelName == node.SelectSingleNode("SceneName").InnerText)
                    {

                        if (Body.name == "AI Josh")
                        {
                            node.SelectSingleNode("AI/JoshAI/X").InnerText = Body.position.x.ToString();
                            node.SelectSingleNode("AI/JoshAI/Y").InnerText = Body.position.y.ToString();
                            node.SelectSingleNode("AI/JoshAI/Action").InnerText = "Event";
                            node.SelectSingleNode("AI/JoshAI/EventType").InnerText = EventType.ToString();
                            node.SelectSingleNode("AI/JoshAI/CaseStep").InnerText = EventStepCase.ToString();
                        }
                        else if (Body.name == "AI Matt")
                        {
                            node.SelectSingleNode("AI/MattAI/X").InnerText = Body.position.x.ToString();
                            node.SelectSingleNode("AI/MattAI/Y").InnerText = Body.position.y.ToString();
                            node.SelectSingleNode("AI/MattAI/Action").InnerText = "Event";
                            node.SelectSingleNode("AI/MattAI/EventType").InnerText = EventType.ToString();
                            node.SelectSingleNode("AI/MattAI/CaseStep").InnerText = EventStepCase.ToString();
                        }
                        else if (Body.name == "AI Kate")
                        {
                            node.SelectSingleNode("AI/KateAI/X").InnerText = Body.position.x.ToString();
                            node.SelectSingleNode("AI/KateAI/Y").InnerText = Body.position.y.ToString();
                            node.SelectSingleNode("AI/KateAI/Action").InnerText = "Event";
                            node.SelectSingleNode("AI/KateAI/EventType").InnerText = EventType.ToString();
                            node.SelectSingleNode("AI/KateAI/CaseStep").InnerText = EventStepCase.ToString();
                        }
                        else if (Body.name == "AI April")
                        {
                            node.SelectSingleNode("AI/AprilAI/X").InnerText = Body.position.x.ToString();
                            node.SelectSingleNode("AI/AprilAI/Y").InnerText = Body.position.y.ToString();
                            node.SelectSingleNode("AI/AprilAI/Action").InnerText = "Event";
                            node.SelectSingleNode("AI/AprilAI/EventType").InnerText = EventType.ToString();
                            node.SelectSingleNode("AI/AprilAI/CaseStep").InnerText = EventStepCase.ToString();
                        }
                        else if (Body.name == "AI Ethan")
                        {
                            node.SelectSingleNode("AI/EthanAI/X").InnerText = Body.position.x.ToString();
                            node.SelectSingleNode("AI/EthanAI/Y").InnerText = Body.position.y.ToString();
                            node.SelectSingleNode("AI/EthanAI/Action").InnerText = "Event";
                            node.SelectSingleNode("AI/EthanAI/EventType").InnerText = EventType.ToString();
                            node.SelectSingleNode("AI/EthanAI/CaseStep").InnerText = EventStepCase.ToString();
                        }

                        break;
                    }
                }

                //Save XML
                DoSaveGame.UpdateSaveData(SaveGameDoc);

                Body.GetComponent<AI_Events>().PreformEvent(Body, WalkSpeed, Anim, EventType, Original_X, Original_Y, EventStepCase);
            }

            #endregion
        }
    }
Beispiel #17
0
 /// <summary>
 /// Called when a character takes damage.
 /// </summary>
 /// <param name="caster">Caster</param>
 /// <param name="target">Target</param>
 /// <param name="damage">Damage dealt</param>
 public void OnCharacterDamageDealt(AI_Character caster, AI_Character target, float damage)
 {
     Debug.Log("[AI] Damage dealt (Caster ID: " + caster.CharacterID + ", Target ID: " + target.CharacterID + ", Damage: " + damage + ").");
     caster.OnDamageDealt(target, damage);
     target.OnDamageTaken(caster, damage);
 }
 /// Character started an action
 public AI_Action OnActionStarted(float game_time, EActionCode action_code, AI_Character target)
 {
     this.CurrentAction = new AI_Action(action_code, this, target);
     this.CurrentAction.OnActionStarted(game_time);
     return(this.CurrentAction);
 }
Beispiel #19
0
 /// <summary>
 /// Called when a character dies.
 /// </summary>
 /// <param name="caster">Character</param>
 public void OnCharacterDeath(AI_Character character)
 {
     Debug.Log("[AI] Character died (Character ID: " + character.CharacterID + ").");
     character.OnDeath();
 }
Beispiel #20
0
    public Resource FindClosestResource(AI_Character character, Resource.ResourceType resource)
    {
        int   num  = -1;
        float dist = 9999;

        List <Resource> resourceList;

        if (resource == Resource.ResourceType.Wood)
        {
            resourceList = treeList;
        }
        else if (resource == Resource.ResourceType.Stone)
        {
            resourceList = stoneList;
        }
        else
        {
            return(null);
        }


        if (resourceList.Count <= 0)
        {
            //Debug.Log ("no resource found");
            return(null);
        }


        NavMeshPath path = new NavMeshPath();

        for (int i = 0; i < resourceList.Count; i++)
        {
            if (resourceList [i].Activated == false)
            {
                continue;
            }
            if (!resourceList [i])
            {
                continue;
            }
            if (!Distance.GetPath(character.transform.position, resourceList [i].transform.position, NavMesh.AllAreas, path))
            {
                break;
            }
            else
            {
                if (Distance.GetPathLength(path) < dist)
                {
                    dist = Distance.GetPathLength(path);
                    num  = i;
                }
            }
        }

        if (num == -1)
        {
            return(null);
        }

        return(resourceList [num]);
    }
Beispiel #21
0
    /// <summary>
    /// Thinks the next player action.
    /// </summary>
    public void ThinkAnticipation()
    {
        Debug.Assert(this.Characters.ContainsKey(AI_Params.PlayerID), "[AI] Invalid player ID (" + AI_Params.PlayerID + ").");
        AI_Character player  = this.Characters[AI_Params.PlayerID];
        bool         changed = false;

        // Training guard
        if ((player.CurrentAction != null) && (player.CurrentAction.ActionCode == EActionCode.ActionCodeGuard))
        {
            this.TrainAnticipation(player, EActionCode.ActionCodeGuard);
        }

        // Training idle
        if ((player.CurrentAction == null) || (player.CurrentAction.ActionCode == EActionCode.ActionCodeNoAction))
        {
            this.TrainAnticipation(player, EActionCode.ActionCodeNoAction);
        }

        // Decaying anticipation probability
        if (this.LastUpdateTime > this.Anticipation_ActionTime)
        {
            this.Anticipation_Probability -= this.LastUpdateTime - this.Anticipation_ActionTime;
            this.Anticipation_ActionTime   = this.LastUpdateTime;
            // Reset anticipation after a while
            if (this.Anticipation_Probability < 0.0f)
            {
                this.Anticipation_Probability = 0.0f;
                this.Anticipation_ActionCode  = EActionCode.ActionCodeNoAction;
            }
        }

        float[] outputs;
        AI_DeepLearningNetwork network;

        // Trying different anticipation timings
        for (float t = 0.1f; t <= 1.0f; t += 0.1f)
        {
            // We will add the anticipation results from each AI for each action in this array
            float[] actions = new float[(int)EActionCode.Count];
            for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
            {
                actions[(int)code] = 0.0f;
            }

            // Each AI character participates in the anticipation
            foreach (AI_Character c in this.Characters.Values)
            {
                if (c.CharacterType == ECharacterType.CharacterTypeEnemy && c.IsAlive)
                {
                    // Anticipation from current/previous player action
                    if (player.CurrentAction != null)
                    {
                        network = this.Networks_Anticipation_1[player.CurrentAction.ActionCode];
                        outputs = network.Think(new float[] {
                            Vector3.Distance(c.PositionIn(t), player.PositionIn(t)),
                            Vector3.Angle(player.Direction, c.PositionIn(t) - player.PositionIn(t)),
                            Vector3.Angle(c.Direction, player.PositionIn(t) - c.PositionIn(t)),
                            t + this.LastUpdateTime - player.CurrentAction.CastTime
                        }, network.Variance);
                        for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
                        {
                            actions[(int)code] += outputs[(int)code];
                        }
                    }
                    else if (player.PreviousAction != null)
                    {
                        network = this.Networks_Anticipation_1[player.PreviousAction.ActionCode];
                        outputs = network.Think(new float[] {
                            Vector3.Distance(c.PositionIn(t), player.PositionIn(t)),
                            Vector3.Angle(player.Direction, c.PositionIn(t) - player.PositionIn(t)),
                            Vector3.Angle(c.Direction, player.PositionIn(t) - c.PositionIn(t)),
                            t + this.LastUpdateTime - player.PreviousAction.CastTime
                        }, network.Variance);
                        for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
                        {
                            actions[(int)code] += outputs[(int)code];
                        }
                    }

                    // Anticipation from current AI action
                    if (c.CurrentAction != null)
                    {
                        network = this.Networks_Anticipation_2[c.CurrentAction.ActionCode];
                        outputs = network.Think(new float[] {
                            Vector3.Distance(c.PositionIn(t), player.PositionIn(t)),
                            Vector3.Angle(player.Direction, c.PositionIn(t) - player.PositionIn(t)),
                            Vector3.Angle(c.Direction, player.PositionIn(t) - c.PositionIn(t)),
                            t + this.LastUpdateTime - c.CurrentAction.CastTime
                        }, network.Variance);
                        for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
                        {
                            actions[(int)code] += outputs[(int)code];
                        }
                    }
                    else
                    {
                        network = this.Networks_Anticipation_2[EActionCode.ActionCodeNoAction];
                        outputs = network.Think(new float[] {
                            Vector3.Distance(c.PositionIn(t), player.PositionIn(t)),
                            Vector3.Angle(player.Direction, c.PositionIn(t) - player.PositionIn(t)),
                            Vector3.Angle(c.Direction, player.PositionIn(t) - c.PositionIn(t)),
                            t
                        }, network.Variance);
                        for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
                        {
                            actions[(int)code] += outputs[(int)code];
                        }
                    }
                }
            }

            // Choosing the most likely action
            for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
            {
                if (this.Anticipation_Probability < actions[(int)code])
                {
                    this.Anticipation_Probability = actions[(int)code];
                    this.Anticipation_ActionCode  = code;
                    this.Anticipation_ActionTime  = this.LastUpdateTime + t;
                    changed = true;
                }
            }
        }

        if (changed)
        {
            Debug.Log("[AI] Anticipating player action " + this.Anticipation_ActionCode + " in " + (this.Anticipation_ActionTime - this.LastUpdateTime) + "s.");
        }
    }
Beispiel #22
0
    /// <summary>
    /// Thinks the orders for AI characters.
    /// </summary>
    public void ThinkAction()
    {
        Debug.Assert(this.Characters.ContainsKey(AI_Params.PlayerID), "[AI] Invalid player ID (" + AI_Params.PlayerID + ").");
        AI_Character player = this.Characters[AI_Params.PlayerID];

        foreach (AI_Character c in this.Characters.Values)
        {
            if (!c.IsPlayer && c.IsAlive && c.IsIdle)
            {
                AI_DeepLearningNetwork network;
                float[] outputs;

                float[] actions = new float[(int)EActionCode.Count];
                for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
                {
                    actions[(int)code] = 0.0f;
                }

                for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
                {
                    // Action
                    network = this.Networks_Action[code];
                    outputs = network.Think(new float[] {
                        Vector3.Distance(c.Position, player.Position),
                        Vector3.Angle(c.Direction, player.Position - c.Position),
                        Vector3.Angle(player.Direction, c.Position - player.Position)
                    }, network.Variance);
                    actions[(int)code] = outputs[0];

                    // Reaction
                    if (player.CurrentAction != null)
                    {
                        network = this.Networks_Reaction[code][player.CurrentAction.ActionCode];
                        outputs = network.Think(new float[] {
                            Vector3.Distance(c.Position, player.Position),
                            Vector3.Angle(c.Direction, player.Position - c.Position),
                            Vector3.Angle(player.Direction, c.Position - player.Position),
                            this.LastUpdateTime - player.CurrentAction.CastTime
                        }, network.Variance);
                        actions[(int)code] = actions[(int)code] * outputs[0] - outputs[1];
                    }
                    else
                    {
                        network = this.Networks_Reaction[code][this.Anticipation_ActionCode];
                        outputs = network.Think(new float[] {
                            Vector3.Distance(c.Position, player.Position),
                            Vector3.Angle(c.Direction, player.Position - c.Position),
                            Vector3.Angle(player.Direction, c.Position - player.Position),
                            this.LastUpdateTime - this.Anticipation_ActionTime
                        }, network.Variance);
                        actions[(int)code] = actions[(int)code] * outputs[0] - outputs[1];
                    }
                }

                // Choosing the best action
                float       best_action_value = 0.0f;
                EActionCode best_action_code  = EActionCode.ActionCodeNoAction;
                for (EActionCode code = EActionCode.ActionCodeNoAction; code < EActionCode.Count; code++)
                {
                    if (best_action_value < actions[(int)code])
                    {
                        best_action_value = actions[(int)code];
                        best_action_code  = code;
                    }
                }

                // Setting the new order
                switch (best_action_code)
                {
                case EActionCode.ActionCodeAttackLight:
                case EActionCode.ActionCodeAttackHeavy:
                case EActionCode.ActionCodeGuard:
                    Debug.Log("[AI] Set order for character " + c.CharacterID + " : " + best_action_code + ".");
                    AI_Orders.SetOrderForCharacter(c.CharacterID, best_action_code, c.Position, Vector3.Normalize(player.Position - c.Position));
                    break;

                case EActionCode.ActionCodeRoll:
                    Debug.Log("[AI] Set order for character " + c.CharacterID + " : " + best_action_code + ".");
                    float   left_or_right    = (UnityEngine.Random.value >= 0.5) ? 1.0f : -1.0f;
                    Vector3 direction_player = Vector3.Normalize(player.Position - c.Position);
                    Vector3 direction_roll   = new Vector3(-direction_player.x, direction_player.y, direction_player.z) * left_or_right;
                    AI_Orders.SetOrderForCharacter(c.CharacterID, best_action_code, c.Position, direction_roll);
                    break;

                case EActionCode.ActionCodeNoAction:
                    if (Vector3.Distance(player.Position, c.Position) < 100.0f)
                    {
                        Debug.Log("[AI] Set order for character " + c.CharacterID + " : " + best_action_code + " (stay in position).");
                        AI_Orders.SetOrderForCharacter(c.CharacterID, EActionCode.ActionCodeNoAction, c.Position, Vector3.Normalize(player.Position - c.Position));
                    }
                    else
                    {
                        Debug.Log("[AI] Set order for character " + c.CharacterID + " : " + best_action_code + " (move towards player).");
                        AI_Orders.SetOrderForCharacter(c.CharacterID, EActionCode.ActionCodeNoAction, player.Position, Vector3.Normalize(player.Position - c.Position));
                    }
                    break;
                }
            }
        }
    }