Ejemplo n.º 1
0
        /// <summary>
        /// Check visibility from this npc to the given npc
        /// </summary>
        /// <param name="npc">other npc on which is testing visibility</param>
        /// <returns>true if npc is visible, otherwise false</returns>
        /// <seealso cref="Bresenham"/>
        private bool CheckVisibility(IActing npc)
        {
            List <Point> line    = Helper.Bresenham(this.GetPosition2D(), npc.GetStatus().position);
            List <int>   heights = new List <int>();

            int thisHeight = (int)Map.GetInstance().GetTerrain().Get3Dposition(this.GetPosition2D()).Y + 80;
            int npcHeight  = (int)Map.GetInstance().GetTerrain().Get3Dposition(npc.GetStatus().position).Y + 80;

            foreach (Point p in line)
            {
                int height = (int)this.terrain.Get3Dposition(p).Y;
                if (Map.GetInstance().CellMap[p.X, p.Y].Block && !Map.GetInstance().CellMap[p.X, p.Y].Danger && !Map.GetInstance().CellMap[p.X, p.Y].Player)
                {
                    height += 200;
                }
                heights.Add(height);
            }

            Vector3 npc1, npc2;

            npc2 = new Vector3(this.x, thisHeight, this.y);
            npc1 = new Vector3(npc.GetStatus().position.X, npcHeight, npc.GetStatus().position.Y);

            //Vector3 u = npc2 - npc1;
            //Vector3 n = Vector3.Cross(u, new Vector3(0,1,0));
            float localHeight;

            for (int i = 0; i < line.Count; i++)
            {
                localHeight = npc1.Y + ((line[i].X - npc1.X) * (npc2.Y - npc1.Y)) / (npc2.X - npc1.X);
                //localHeight2 = npc1.Y + ((line[i].Y - npc1.Z) * (npc2.Y - npc1.Y)) / (npc2.Z - npc1.Z);

                if (localHeight < heights[i])
                {
                    //Logger.AddInfo(this.character.name +  ": Nepritel " + npc.character.name + " neni videt");
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// from generated state-prob pairs choose the best one and returns new Confict state
        /// </summary>
        /// <param name="myself">npc, which is choosing from actions</param>
        /// <param name="enemy">enemy npc on which is the target</param>
        /// <param name="priors">priors from npc character, useless for now</param>
        /// <param name="actionType">type of action</param>
        /// <returns>new confict state</returns>
        public ConflictState GetNextAction(IActing myself, IActing enemy, Priorities priors, out Action selectedAction)
        {
            ConflictState currentState = new ConflictState(myself.GetStatus(), enemy.GetStatus());
            Priorities    priorities   = priors;
            CharacterNPC  myChar       = myself.GetCharacter();

            //if (this.stateSpace.Count == 0)
            //{
            //    CreateStateSpace(currentState, myChar);
            //}

            List <StateProbPairs> expanders = Expand(currentState, myChar);

            StateProbPairs result = new StateProbPairs();

            int lowestCost = int.MaxValue;
            int actionCost = int.MaxValue;

            foreach (StateProbPairs pairs in expanders)
            {
                //if (this.stateSpace.Contains(pairs))
                //{
                //    Logging.Logger.AddInfo(pairs.ToString() + " je obsazeno");
                //}
                actionCost = ComputeCost(currentState, pairs, myChar);

                if (actionCost < lowestCost && actionCost >= 0)
                {
                    result     = pairs;
                    lowestCost = actionCost;
                }
            }
            if (result.states == null)
            {
                result.states.Add(currentState);
                Action empty = new Action();
                empty.name    = "empty";
                empty.time    = 5000;
                result.action = empty;
                result.probabilities.Add(100);
            }

            int index = 0;

            if (result.probabilities.Count > 1)
            {
                int randChoose = rand.Next(100);
                if (randChoose < result.probabilities[0])
                {
                    index = 0;
                }
                else if (randChoose < result.probabilities[0] + result.probabilities[1])
                {
                    index = 1;
                }
                else
                {
                    if (result.states.Count > 2)
                    {
                        index = 2;
                    }
                }
            }

            if (index >= result.states.Count)
            {
                index = 0;
            }

            Logging.Logger.AddInfo(myChar.name + ": " + result.action.ToString() + " proti " + enemy.GetCharacter().name + ", cost=" + lowestCost + ", efekt: " + index);
            myself.SetCoolDown(result.action.time);

            selectedAction  = result.action;
            this.lastAction = selectedAction;
            //return result.states[index];
            return(result.states[0]);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// ctor, create info about NPC
 /// </summary>
 /// <param name="npc"></param>
 public NpcInfo(IActing npc)
 {
     this.status    = npc.GetStatus();
     this.character = npc.GetCharacter();
 }
 public ConflictState GetNextAction(IActing myself, IActing enemy, Priorities priors, out Action selectedAction)
 {
     //TODO dodelat
     selectedAction = this.attackActions[0];
     return(new ConflictState(myself.GetStatus(), enemy.GetStatus()));
 }
Ejemplo n.º 5
0
 /// <summary>
 /// NPC is attacked by unseen attacker
 /// </summary>
 /// <param name="enemy"></param>
 public void RegisterAttack(IActing enemy)
 {
     this.TargetedEnemy = enemy;
 }
Ejemplo n.º 6
0
        /// <summary>
        /// update NPC's map, check if is anybody in visual range
        /// </summary>
        /// <param name="npcs">list of all npcs</param>
        /// <param name="step">duration from last update in miliseconds, typicaly little part of second</param>
        public void UpdateNPC(List <NPC> npcs, float step)
        {
            if (!this.currentStatus.alive || this.currentStatus.hp <= 0)
            {
                return;
            }

            UpdateTime(step);
            UpdateTask();

            #region check npcs and player

            int seenEnemyCount = 0;
            int nearest        = this.visualRange + 1000;
            int distance;
            this.currentStatus.nearEnemies.Clear();
            //check npcs
            if (npcs.Count > 1) //if only one NPC -> this one
            {
                foreach (NPC npc in npcs)
                {
                    if (this.character.type == NPCType.villager)
                    {
                        this.controlMechanism.Update();
                        return;
                    }
                    else if (this.character.type == NPCType.guard)
                    {
                        //guards will atack only player
                        break;
                    }
                    else if (this.Equals(npc))
                    {
                        continue; //this npc
                    }
                    else if (npc.character.type == NPCType.villager || npc.character.type == NPCType.boss ||
                             npc.character.type == NPCType.guard)
                    {
                        //don't attack villagers and guards and boss
                        continue;
                    }
                    else if (this.character.type == npc.character.type && npc.character.type != NPCType.enemy)
                    {
                        //not enemy
                        continue;
                    }
                    distance = CalculateDistance(npc.GetPosition2D());

                    if (distance < this.visualRange && CheckVisibility(npc))
                    {
                        seenEnemyCount++;
                        this.currentStatus.nearEnemies.Add(npc);

                        if (distance < nearest) //TODO lip vybirat target
                        {
                            this.targetedEnemy = npc;
                            nearest            = distance;
                        }
                    }
                }
            }

            //check player
            if (CanAttackPlayer)
            {
                distance = CalculateDistance(this.terrain.GetPlayerPosition());
                if (distance < this.visualRange && CheckVisibility(GamePlayer.GetPlayer()))
                {
                    IActing player = GamePlayer.GetPlayer();
                    seenEnemyCount++;
                    this.currentStatus.nearEnemies.Add(GamePlayer.GetPlayer());
                    if (distance < nearest)
                    {
                        this.targetedEnemy = GamePlayer.GetPlayer();
                        nearest            = distance;
                    }
                }
            }
            #endregion

            int targetingEnemyPower = 0;
            foreach (IActing npc in this.currentStatus.nearEnemies)
            {
                if (npc.GetTargetedEnemy() == (this as IActing))
                {
                    targetingEnemyPower += ((int)npc.GetStatus().hp *npc.GetCharacter().level);
                }
            }

            //update status
            this.currentStatus.enemySeen  = seenEnemyCount;
            this.currentStatus.enemyPower = targetingEnemyPower;
            this.currentStatus.position   = this.GetPosition2D();
            this.currentStatus.cooldown   = this.cooldown;


            this.controlMechanism.Update();

            this.step = step;
        }
Ejemplo n.º 7
0
 public void Dispose()
 {
     this.targetedEnemy = null;
     this.taskStack     = null;
     this.pathFinding   = null;
 }