void Start()
 {
     currentPlayerTile  = TMapController.M.land.WorldToCell(transform.position);
     transform.position = TMapController.M.land.CellToWorld(currentPlayerTile);
     hitpoints          = maxHP;
     currentState       = unitState.idle;
 }
 public void SetPosition(Vector3Int v)
 {
     currentPlayerTile.x = v.x;
     currentPlayerTile.y = v.y;
     transform.position  = TMapController.M.land.CellToWorld(currentPlayerTile);
     currentState        = unitState.moved;
 }
    public void ChangeToMove(Hex newHex)
    {
        attachedHex.attachedObject = null;
        attachedHex = newHex;

        state = unitState.Moving;
    }
        public void turnTickAI_Paladin(Map map)
        {
            paladinDuration -= 1;
            if (map.units.Contains(paladinTarget) == false)
            {
                this.task  = null;
                this.state = unitState.investigator;
                map.world.prefabStore.popMsg(this.getName() + " has completed their quest to hunt down " + paladinTarget.getName() + ", and can now return to their normal duties.");
                return;
            }
            if (paladinDuration <= 0)
            {
                this.task  = null;
                this.state = unitState.investigator;
                map.world.prefabStore.popMsg(this.getName() + " has run out of supplies to pursue " + paladinTarget.getName() + " and must end their quest.");
                return;
            }

            if (task == null)
            {
                task = new Task_HuntEnthralled_PaladinState(this, paladinTarget);
            }

            task.turnTick(this);
        }
    public void endMove(Vector3Int destTile)
    {
        if (TMapController.M.moving == null)
        {
            //print("moving == null | "+ currentTurn +" | "+ roundState);
            return;
        }

        switch (currentState)
        {
        case unitState.idle:
            if (withinRange.Contains(destTile))
            {
                previousTile = currentPlayerTile;
                SetPosition(destTile);
                currentState = unitState.moved;
                TMapController.M.roundState = TMapController.mapRound.attacking;
                clearMove();
                startAttack(gameObject, currentPlayerTile, minAtkRange, maxAtkRange);
                _army.UnitMoved(this);
                break;
            }
            break;

        case unitState.moved:
            foreach (Vector3Int v in withinRange)
            {
                if (destTile == v)
                {
                    foreach (GameObject unit in GameObject.FindGameObjectsWithTag("Unit"))
                    {
                        if (TMapController.M.land.WorldToCell(unit.transform.position) == v)
                        {
                            //int dmg = TMapController.M.moving.GetComponent<Unit>().Attack();
                            //print("damage: " + dmg);
                            //print("killed: " + unit.GetComponent<Unit>().TakeDamage(dmg));
                            //unit.GetComponent<Unit>().TakeDamage(dmg);
                            int dmg = this.attackRoll;
                            if (unit.GetComponent <Unit>().AttackHit(dmg))
                            {
                                unit.GetComponent <Unit>().TakeDamage(dmg);
                            }
                            else
                            {
                                unit.GetComponent <HealthDisplay>().ShowDmg("Miss!");
                            }
                            TMapController.M.moving.GetComponent <Unit>().currentState = unitState.idle;
                            TMapController.M.roundState = TMapController.mapRound.moving;
                            clearMove();
                            TMapController.M.NextTurn();
                            break;
                        }
                    }
                }
            }
            break;
        }
    }
 public void Undo()
 {
     SetPosition(previousTile);
     _army.UndoMove(this);
     TMapController.M.moving     = null;
     currentState                = unitState.idle;
     TMapController.M.roundState = TMapController.mapRound.moving;
     TMapController.M.ClearHighlights();
 }
Exemplo n.º 7
0
 public void init(AI ai, Environment env, unitData data, HpBar hpbar)
 {
     this.ai    = ai;
     this.env   = env;
     this.data  = data;
     this.state = new unitState();
     this.hpbar = hpbar;
     this.data._onLifeChange += hpbarCallBack;
     this.data._onDeath       = onUnitDeath;
 }
        public void changeState(unitState neo)
        {
            state = neo;
            if (task is Task_Disrupted == false)
            {
                task = null;
            }

            if (person != null && neo == unitState.investigator || neo == unitState.paladin)
            {
                person.watched = true;
            }
            turnLastChangedRole = location.map.turn;
        }
 //This method returns true if the unit was killed by an attack
 public bool TakeDamage(int damage)
 {
     hitpoints -= damage - defense;
     print("hit for " + damage + " (- " + defense + ")");
     gameObject.GetComponentInChildren <Slider>().value = (float)hitpoints / maxHP;
     gameObject.GetComponent <HealthDisplay>().ShowDmg((damage - defense).ToString());
     if (hitpoints <= 0)           //+ _army.armyBonus)) {
     {
         print("Unit killed!");
         currentState = unitState.dead;
         //Destroy(gameObject);
         gameObject.GetComponent <SpriteRenderer>().sprite = skullSprite;
         if (gameObject.transform.localScale.x == 2)
         {
             RescaleDeadKnight();
         }
         _army.UnitDied(this);
         ColorOn(false);
         return(true);
     }
     return(false);
 }
 public void EndTurn()
 {
     currentState = unitState.idle;
 }
 public void StartTurn()
 {
     currentState = unitState.idle;
     previousTile = currentPlayerTile;
 }
    IEnumerator Idle()
    {
        #region Idle
        while (state == unitState.Idle)
        {
            Debug.Log("Idle " + unitName);
            if (attachedHex.selected == true)
            {
                Debug.Log("Selecting Position " + unitName);
                state = unitState.SelectingPosition;
            }
            yield return(0);
        }
        #endregion
        #region Selecting
        while (state == unitState.SelectingPosition)
        {
            int currentX = attachedHex.horiPoint;
            int currentY = attachedHex.vertPoint;

            if (attachedHex.oddLane == true)
            {
                if (currentY < 7)
                {
                    movableHexes.Add(Layout.LayoutManager.hexPoints[currentY + 1, currentX]);
                    if (currentX < 5)
                    {
                        movableHexes.Add(Layout.LayoutManager.hexPoints[currentY + 1, currentX + 1]);
                    }
                    if (currentX > 0)
                    {
                        movableHexes.Add(Layout.LayoutManager.hexPoints[currentY + 1, currentX - 1]);
                    }
                }

                if (currentY > 0)
                {
                    movableHexes.Add(Layout.LayoutManager.hexPoints[currentY - 1, currentX]);
                }
                if (currentX > 0)
                {
                    movableHexes.Add(Layout.LayoutManager.hexPoints[currentY, currentX - 1]);
                }
                if (currentX < 5)
                {
                    movableHexes.Add(Layout.LayoutManager.hexPoints[currentY, currentX + 1]);
                }
            }
            else
            {
                if (currentY > 0)
                {
                    movableHexes.Add(Layout.LayoutManager.hexPoints[currentY - 1, currentX]);


                    if (currentX > 0)
                    {
                        movableHexes.Add(Layout.LayoutManager.hexPoints[currentY - 1, currentX - 1]);
                    }
                }
                if (currentX > 0)
                {
                    movableHexes.Add(Layout.LayoutManager.hexPoints[currentY, currentX - 1]);
                }

                if (currentY < 7)
                {
                    movableHexes.Add(Layout.LayoutManager.hexPoints[currentY + 1, currentX]);
                }
                if (currentX < 5)
                {
                    movableHexes.Add(Layout.LayoutManager.hexPoints[currentY, currentX + 1]);
                    if (currentY > 0)
                    {
                        movableHexes.Add(Layout.LayoutManager.hexPoints[currentY - 1, currentX + 1]);
                    }
                }
            }


            foreach (GameObject highlighedHex in movableHexes)
            {
                Hex newHex = highlighedHex.GetComponent <Hex>();
                if (newHex.attachedObject != null)
                {
                    newHex.movable = false;

                    if (newHex.attachedObject.GetComponent <BoardUnit>().blue == false)
                    {
                        newHex.movable     = false;
                        newHex.attachedRed = true;
                    }
                }
                else
                {
                    newHex.movable = true;
                }
            }

            yield return(0);
        }
        #endregion
        #region Moving
        while (state == unitState.Moving)
        {
            Debug.Log("Moving" + unitName);

            //Moving Towards new Hexagon
            if (this.gameObject.transform.position != attachedHex.attachPoint.transform.position)
            {
                this.gameObject.transform.position = Vector3.MoveTowards(this.gameObject.transform.position, attachedHex.attachPoint.transform.position, transferSpeed);

                foreach (GameObject oldHex in movableHexes)
                {
                    Hex hex = oldHex.GetComponent <Hex>();
                    hex.movable = false;
                }
            }
            if (this.gameObject.transform.position == attachedHex.attachPoint.transform.position)
            {
                movableHexes.Clear();
                state = unitState.Idle;
                StartCoroutine(Idle());
            }
            yield return(0);
        }
        #endregion
        #region Attacking
        while (state == unitState.Attacking)
        {
            foreach (GameObject oldHex in movableHexes)
            {
                Hex hex = oldHex.GetComponent <Hex>();
                hex.movable = false;
            }
            movableHexes.Clear();
            state = unitState.Idle;
            StartCoroutine(Idle());

            yield return(0);
        }
        yield return(null);

        #endregion
    }
 public void ChangeToAttack()
 {
     state = unitState.Attacking;
 }
        public static double getSwitchUtility(Person person, Unit_Investigator swappable, unitState hypo)
        {
            double value = 0;

            double worstMilitaryFear = 0;

            foreach (ThreatItem item in person.threatEvaluations)
            {
                if (item.group != null)
                {
                    if (item.threat > worstMilitaryFear)
                    {
                        worstMilitaryFear = item.threat;
                    }
                }
            }
            double[] weights           = new double[] { person.threat_agents.threat, worstMilitaryFear, person.threat_plague.threat, person.threat_agents.threat };
            double[] currentAllocation = new double[4];
            double[] futureAllocation  = new double[4];

            if (weights[0] < 50)
            {
                weights[0] = 50;//Try to keep at least some people watching the criminal situation
            }

            int specialisationWeight = 3;

            foreach (Unit u in person.map.units)
            {
                if (u.society == person.society && u is Unit_Investigator)
                {
                    Unit_Investigator existing = (Unit_Investigator)u;
                    if (existing.state == unitState.basic)
                    {
                        //Basic covers all jobs
                        for (int i = 0; i < currentAllocation.Length; i++)
                        {
                            currentAllocation[i] += 1;
                            if (u != swappable)
                            {
                                futureAllocation[i] += 1;
                            }
                        }
                    }
                    else if (existing.state == unitState.investigator || existing.state == unitState.paladin)
                    {
                        currentAllocation[0] += specialisationWeight;
                        if (u != swappable)
                        {
                            futureAllocation[0] += specialisationWeight;
                        }
                    }
                    else if (existing.state == unitState.knight)
                    {
                        currentAllocation[1] += specialisationWeight;
                        if (u != swappable)
                        {
                            futureAllocation[1] += specialisationWeight;
                        }
                    }
                    else if (existing.state == unitState.medic)
                    {
                        currentAllocation[2] += specialisationWeight;
                        if (u != swappable)
                        {
                            futureAllocation[2] += specialisationWeight;
                        }
                    }
                    else if (existing.state == unitState.inquisitor)
                    {
                        currentAllocation[3] += specialisationWeight;
                        if (u != swappable)
                        {
                            futureAllocation[3] += specialisationWeight;
                        }
                    }
                }
            }
            //What would the future state look like if this agent swapped?
            if (hypo == unitState.basic)
            {
                for (int i = 0; i < currentAllocation.Length; i++)
                {
                    futureAllocation[i] += 1;
                }
            }
            else if (hypo == unitState.paladin || hypo == unitState.investigator)
            {
                futureAllocation[0] += specialisationWeight;
            }
            else if (hypo == unitState.knight)
            {
                futureAllocation[1] += specialisationWeight;
            }
            else if (hypo == unitState.medic)
            {
                futureAllocation[2] += specialisationWeight;
            }
            else if (hypo == unitState.inquisitor)
            {
                futureAllocation[3] += specialisationWeight;
            }

            double normA = 0;
            double normB = 0;
            double normC = 0;

            for (int i = 0; i < currentAllocation.Length; i++)
            {
                normA += currentAllocation[i];
                normB += weights[i];
                normC += futureAllocation[i];
            }
            for (int i = 0; i < currentAllocation.Length; i++)
            {
                if (normA != 0)
                {
                    currentAllocation[i] /= normA;
                }
                if (normB != 0)
                {
                    weights[i] /= normB;
                }
                if (normC != 0)
                {
                    futureAllocation[i] /= normC;
                }
            }

            //We now want to ask if swapping gets us closer to ideal distribution
            //Squared Euclidean metric
            double presentDistance = 0;
            double futureDistance  = 0;

            //string msgCur = "";
            //string msgFuture = "";
            //string msgWeights = "";
            for (int i = 0; i < futureAllocation.Length; i++)
            {
                //msgFuture += Eleven.toFixedLen(futureAllocation[i], 4) + " ";
                //msgCur += Eleven.toFixedLen(currentAllocation[i], 4) + " ";
                //msgWeights += Eleven.toFixedLen(weights[i], 4) + " ";
                //World.log("Swap hypothesis " + i + " " + currentAllocation[i] + " " + futureAllocation[i]);
                presentDistance += (currentAllocation[i] - weights[i]) * (currentAllocation[i] - weights[i]);
                futureDistance  += (futureAllocation[i] - weights[i]) * (futureAllocation[i] - weights[i]);
            }
            //World.log("Threat weights: " + msgWeights);
            //World.log("Hypotheatical : " + msgFuture + " dist " + Eleven.toFixedLen(futureDistance, 5));
            //World.log("Current       : " + msgCur + " dist " + Eleven.toFixedLen(presentDistance,5));

            return(presentDistance - futureDistance);//We want to minimise the distance. If swapping moves us closer then futureDist is smaller than present dist, so this becomes positive
        }
        public void turnTickAI_Investigator(Map map)
        {
            foreach (Evidence ev in evidenceCarried)
            {
                if (ev.pointsTo != null && ev.pointsTo != this)
                {
                    if (huntableSuspects.Contains(ev.pointsTo) == false)
                    {
                        huntableSuspects.Add(ev.pointsTo);
                    }
                }
            }

            if (this.location.soc == society)
            {
                sinceHome = 0;
                if (this.hp < maxHp && task == null && location.settlement != null)
                {
                    task = new Task_Resupply();
                }
            }
            else
            {
                sinceHome += 1;
            }

            //Scan local units
            if (map.param.unit_investigatorsSeeEnthralled == 1)
            {
                foreach (Unit u in location.units)
                {
                    if (u.isEnthralled() && u.person != null && this.person.getRelation(u.person).suspicion > 0)
                    {
                        if (this.person != null && u.person != null)
                        {
                            this.person.getRelation(u.person).suspicion = Math.Min(1, this.person.getRelation(u.person).suspicion + map.param.unit_suspicionFromProximity);
                            map.addMessage(this.getName() + " has gained suspicion of " + u.getName(), MsgEvent.LEVEL_ORANGE, false, location.hex);
                        }
                    }
                }
            }


            if (task != null)
            {
                task.turnTick(this);
                return;
            }

            if (shouldBePaladin(map))
            {
                Unit   target   = null;
                double bestDist = -1;
                foreach (Unit u in huntableSuspects)
                {
                    if (map.units.Contains(u))
                    {
                        double dist = map.getStepDist(u.location, location);
                        if (bestDist == -1 || dist < bestDist)
                        {
                            bestDist = dist;
                            target   = u;
                        }
                    }
                }

                task             = new Task_HuntEnthralled_PaladinState(this, target);
                paladinTarget    = target;
                state            = unitState.paladin;
                lastTurnPromoted = map.turn;
                if (hostility.Contains(paladinTarget) == false)
                {
                    hostility.Add(paladinTarget);
                }
                paladinDuration = map.param.unit_paladin_promotionDuration;
                map.world.prefabStore.popMsgAgent(this, target, this.getName() + " has found evidence that " + paladinTarget.getName() + " is in league with the darkness," +
                                                  " and has been granted the powers of the paladin, to hunt them down for a duration. They are currently in " + location.getName() + ".");

                //Update your graphic
                if (this.outer != null)
                {
                    this.outer.checkData();
                }
                return;
            }
            else if (location.evidence.Count > 0)
            {
                task = new Task_Investigate();
            }
            else if (sinceHome > wanderDur)
            {
                task = new Task_GoToSocialGroup(society);
            }
            else
            {
                task = new Task_Wander();
            }


            task.turnTick(this);
        }