コード例 #1
0
    private void Awake()
    {
        Messaging.Player.Position.AddListener((v) =>
        {
            Vec2I g = TheGrid.GridPosition(v);

            if (lastPlayerGridPosition == g)
            {
                return;
            }

            lastPlayerGridPosition = g;

            int gridDistance = Vec2I.Max(g, TheGrid.GridPosition(transform.position));

            if (gridDistance <= ShowTextDistance)
            {
                if (floatingText == null)
                {
                    floatingText = Messaging.GUI.FloatingText(transform.position + Offset, ShowText, TextColorFar);
                }

                floatingText.color = gridDistance <= UseDistance ? TextColorClose : TextColorFar;
            }
            else if (floatingText != null && gridDistance > ShowTextDistance)
            {
                Destroy(floatingText.gameObject);
                floatingText = null;
            }
        });
    }
コード例 #2
0
ファイル: ClawerBehavior.cs プロジェクト: RistoPaasivirta/IOX
    private void OnInputRequest(ref MonsterCharacter.InputFrame frame)
    {
        if (target == null)
            return;

        if (dualSwingTimer > 0f)
            dualSwingTimer -= Time.deltaTime;

        frame.LocalTransform = true;

        int steps = Vec2I.Max(thing.gridPos, target.thingController.gridPos);

        if (steps <= MaxAttackConsiderationStepCount)
        {
            frame.WantDirection = TowardsTarget;

            if (character.CurrentWeapon.IsReady && character.CurrentOffhand.IsReady)
            {
                if (Random.value > .5f)
                    frame.PrimaryAttackContinuous = true;
                else
                    frame.SecondaryAttackContinuous = true;

                dualSwingTimer = DualSwingDelay;
            }
            else if (dualSwingTimer <= 0f)
            {
                frame.PrimaryAttackContinuous = true;
                frame.SecondaryAttackContinuous = true;
            }

            frame.up = 1f;
            return;
        }
                
        if (CanSeeTargetGrid)
        {
            frame.WantDirection = TowardsTarget;
            if (steps > StopMovingStepCount)
                frame.up = 1f;

            return;
        }

        Vec2I smart = SmartMove;
        if (SmartMove != Vec2I.zero)
        {
            frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(smart.y, smart.x) * Mathf.Rad2Deg);
            if (steps > StopMovingStepCount)
                frame.up = 1;
        }
    }
コード例 #3
0
ファイル: AxMath.cs プロジェクト: RistoPaasivirta/IOX
    //returns best step direction towards target
    public static int RogueDirection(Vec2I origo, Vec2I target)
    {
        if (origo.x == target.x && origo.y == target.y)
        {
            return(0);
        }

        Vec2I d  = target - origo;
        int   dx = Mathf.Abs(d.x);
        int   dy = Mathf.Abs(d.y);

        return(Vec2I.Max(origo, target) / 2 >= Mathf.Abs(dx - dy) ?
               (d.x > 0 ? (d.y > 0 ? 6 : 4) : (d.y > 0 ? 8 : 2)) :
               (dx > dy ? (d.x > 0 ? 5 : 1) : (d.y > 0 ? 7 : 3)));
    }
コード例 #4
0
    public void Use(MonsterCharacter caller)
    {
        if (AllowOnlyPlayer)
        {
            if (caller.GetComponent <PlayerControls>() == null)
            {
                return;
            }
        }

        if (Vec2I.Max(TheGrid.GridPosition(caller.transform.position), TheGrid.GridPosition(transform.position)) > UseDistance)
        {
            return;
        }

        OnUse.Invoke(caller);
        AfterUse.Invoke();
    }
コード例 #5
0
    private void FillInputFrame(ref MonsterCharacter.InputFrame frame)
    {
        frame.up            = dir.y;
        frame.right         = dir.x;
        frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dir.y, dir.x) * Mathf.Rad2Deg);

        if (timer > 0f)
        {
            return;
        }

        timer = DecisionTime;
        dir   = Vector2.zero;

        Mouse.UpdateWorldPosition();

        if (Mouse.InWorld)
        {
            if (Mouse.GridPosition != lastMouseGrid)
            {
                Vec2I a = thing.gridPos;
                Vec2I b = Mouse.GridPosition;

                if (AI.GetPath(a, b, Vec2I.Max(a, b), out Vec2I[] path))
コード例 #6
0
    private void MoveOut(ref MonsterCharacter.InputFrame frame)
    {
        if (target != null)
        {
            character.OnInputRequest = Hesitate;
            return;
        }

        if (PlayerTooFar)
        {
            character.OnInputRequest = StandAround;
        }

        if (moveTarget != Vec2I.illegalMin)
        {
            Vector2 dif = TheGrid.WorldPosition(moveTarget) - (Vector2)transform.position;

            if (dif != Vector2.zero)
            {
                dir = dif.normalized;
            }

            frame.up    = dir.y;
            frame.right = dir.x;

            if (LookAtMoveDir)
            {
                lookDir = dir;
            }

            frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg);
        }

        if (decisionTimer > 0f)
        {
            decisionTimer -= Time.deltaTime;
            return;
        }

        decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y);

        LookAtMoveDir = Random.value < LookAtMoveDirChance;

        if (targetRoom < 0 || targetRoom >= Room.Rooms.Length)
        {
            return;
        }

        Room room = Room.Rooms[targetRoom];

        if (Vec2I.Max(room.gridPos, thing.gridPos) < 3)
        {
            if (MissionObjective == 0)
            {
                Messaging.GUI.CommsMessage.Invoke(0, OnExitMessagePortrait, OnExitMessage);
                MissionObjective++;
                Messaging.Mission.MissionStatus.Invoke(true);
            }

            Instantiate(TeleportEffect, transform.position, Quaternion.identity, LevelLoader.TemporaryObjects);

            Destroy(gameObject);
        }

        if (!AI.RoomPath(thing.gridPos, room, MaxSteps, out Vec2I[] path))
コード例 #7
0
ファイル: AlienBehavior.cs プロジェクト: RistoPaasivirta/IOX
    private void OnInputRequest(ref MonsterCharacter.InputFrame frame)
    {
        if (target == null)
        {
            return;
        }

        frame.WantDirection = TowardsTarget;

        if (character.ChargePoints >= MinChargePointsForSkill)
        {
            if (character.Skills.Length > 0)
            {
                if (character.Skills[0] != null)
                {
                    if (character.SkillCooldowns[0] <= 0f)
                    {
                        if (CanSeeTargetGrid)
                        {
                            character.Skills[0].Activate(character, 0);
                        }
                    }
                }
            }
        }

        if (dualSwingTimer > 0f)
        {
            dualSwingTimer -= Time.deltaTime;
        }

        int steps = Vec2I.Max(thing.gridPos, target.thingController.gridPos);

        if (steps <= MaxAttackConsiderationStepCount)
        {
            if (character.CurrentWeapon.IsReady && character.CurrentOffhand.IsReady)
            {
                if (Random.value > .5f)
                {
                    frame.PrimaryAttackContinuous = true;
                }
                else
                {
                    frame.SecondaryAttackContinuous = true;
                }

                dualSwingTimer = DualSwingDelay;
            }
            else if (dualSwingTimer <= 0f)
            {
                frame.PrimaryAttackContinuous   = true;
                frame.SecondaryAttackContinuous = true;
            }
        }

        frame.LocalTransform = false;

        if (chargeTimer > 0f)
        {
            if (AngleToTarget(target.transform.position) > MaxChargeAngle)
            {
                chargeTimer = 0f;
            }

            frame.LocalTransform = true;
            chargeTimer         -= Time.deltaTime;
            frame.up             = 1f;
            character.walkSpeed  = RunSpeed;
            character.TurnSpeed  = RunTurnSpeed;
            return;
        }

        if (chargeCooldownTimer > 0f)
        {
            chargeCooldownTimer -= Time.deltaTime;
        }

        character.walkSpeed = walkSpeed;
        character.TurnSpeed = walkTurnSpeed;

        float distanceSqr = (target.transform.position - transform.position).sqrMagnitude;

        if (steps > StopMovingStepCount)
        {
            if (chargeCooldownTimer <= 0f)
            {
                if (distanceSqr >= StopRange * StopRange && distanceSqr <= RunRange * RunRange)
                {
                    if (AngleToTarget(target.transform.position) <= MaxChargeAngle)
                    {
                        if (CanSeeTargetGrid)
                        {
                            chargeTimer         = ChargeTime;
                            chargeCooldownTimer = ChargeCooldown;
                            return;
                        }
                    }
                }
            }
        }

        if (hesitateTimer > 0f)
        {
            hesitateTimer -= Time.deltaTime;
            return;
        }

        if (Random.value < IdleChance)
        {
            frame.up      = 0;
            frame.right   = 0;
            hesitateTimer = Random.Range(IdleTime.x, IdleTime.y);
            return;
        }

        if (Random.value < RandomMoveChance)
        {
            float a = Random.value * Mathf.PI * 2f;
            frame.right = Mathf.Cos(a);
            frame.up    = Mathf.Sin(a);
            return;
        }

        //path find to target
        {
            Vec2I smart = SmartMove;

            frame.up    = smart.y;
            frame.right = smart.x;
        }
    }
コード例 #8
0
    public static bool GetPath(Vec2I StartPos, Vec2I EndPos, int maxDistance, out Vec2I[] path)
    {
        if (StartPos == EndPos)
        {
            path    = new Vec2I[1];
            path[0] = EndPos;
            return(true);
        }

        path = null;

        if (Vec2I.Max(StartPos, EndPos) > maxDistance)
        {
            return(false);
        }
        if (Heatmap.GetNode(EndPos) == null)
        {
            return(false);
        }

        HeatmapNode startNode = Heatmap.GetNode(StartPos);

        if (startNode == null)
        {
            return(false);
        }

        //init arrays
        int arraySize = maxDistance * 2 + 1;

        bool[,] closedCheck   = new bool[arraySize, arraySize];
        bool[,] openCheck     = new bool[arraySize, arraySize];
        Vec2I[,] parent       = new Vec2I[arraySize, arraySize];
        PathStep[,] openArray = new PathStep[arraySize, arraySize];

        //set start point
        BinaryHeap <PathStep> openList = new BinaryHeap <PathStep>(arraySize * arraySize);

        openList.Add(new PathStep(startNode, Heuristic(StartPos, EndPos)));
        openCheck[maxDistance, maxDistance] = true;
        parent[maxDistance, maxDistance]    = StartPos;

        bool found = false;

        while (openList.ItemCount > 0)
        {
            //get top of heap
            PathStep current = openList.RemoveFirst();
            int      cx      = current.node.gridPos.x - StartPos.x + maxDistance;
            int      cy      = current.node.gridPos.y - StartPos.y + maxDistance;
            closedCheck[cx, cy] = true;

            foreach (HeatmapNode neighbor in current.node.neighbors)
            {
                //calculate array position
                int nx = neighbor.gridPos.x - StartPos.x + maxDistance;
                int ny = neighbor.gridPos.y - StartPos.y + maxDistance;

                //cull disallowed
                if (Vec2I.Max(neighbor.gridPos, StartPos) > maxDistance)
                {
                    continue;
                }
                if (closedCheck[nx, ny])
                {
                    continue;
                }
                if (!CanTravel(current.node, neighbor))
                {
                    continue;
                }

                //found target
                if (neighbor.gridPos == EndPos)
                {
                    parent[nx, ny] = current.node.gridPos;
                    found          = true;
                    goto finalize;
                }

                //calculate cost
                int travelCost = current.travelCost + TravelCostAstar(current.node, neighbor);
                int heuristic  = Heuristic(neighbor.gridPos, EndPos);
                int fullCost   = travelCost + heuristic;

                //check if we can update parent to better
                if (openCheck[nx, ny])
                {
                    if (openArray[nx, ny].fullCost > fullCost)
                    {
                        openArray[nx, ny].travelCost = travelCost;
                        openArray[nx, ny].heuristic  = heuristic;
                        openArray[nx, ny].fullCost   = fullCost;
                        parent[nx, ny] = current.node.gridPos;
                        openList.UpdateItem(openArray[nx, ny]);
                        continue;
                    }
                    else
                    {
                        continue;
                    }
                }

                //priority sorted by heap
                PathStep step = new PathStep(neighbor, travelCost, heuristic);
                openList.Add(step);
                openArray[nx, ny] = step;
                openCheck[nx, ny] = true;
                parent[nx, ny]    = current.node.gridPos;
            }
        }

finalize:
        if (found)
        {
            SingleLinkedList <Vec2I> list = new SingleLinkedList <Vec2I>();

            Vec2I current = EndPos;
            while (current != StartPos)
            {
                list.InsertFront(current);
                current = parent[current.x - StartPos.x + maxDistance, current.y - StartPos.y + maxDistance];
            }
            list.InsertFront(current); //adds the starting point to the path
            path = list.ToArray();
            return(true);
        }

        return(false);
    }
コード例 #9
0
    public static void FillBreath(HeatmapNode startNode, ref BreathArea breath)
    {
        int maxDistance = breath.maxDistance;
        int arraySize   = breath.size;

        //start sanity check
        if (startNode == null)
        {
            return;
        }
        if (startNode.neighbors.Count == 0)
        {
            return;
        }

        breath.startPos = startNode.gridPos;
        breath.Invalidate();

        //init arrays
        bool[,] closedCheck   = new bool[arraySize, arraySize];
        bool[,] openCheck     = new bool[arraySize, arraySize];
        PathStep[,] openArray = new PathStep[arraySize, arraySize];

        //set start point
        BinaryHeap <PathStep> openList = new BinaryHeap <PathStep>(arraySize * arraySize);

        openList.Add(new PathStep(startNode, 0));
        openCheck[maxDistance, maxDistance] = true;

        //add start breath to area
        breath.exist[maxDistance, maxDistance]      = true;
        breath.steps[maxDistance, maxDistance]      = 0;
        breath.travelCost[maxDistance, maxDistance] = 0;
        breath.parent[maxDistance, maxDistance]     = breath.startPos;

        while (openList.ItemCount > 0)
        {
            //get top of heap
            PathStep current      = openList.RemoveFirst();
            int      cx           = current.node.gridPos.x - breath.startPos.x + maxDistance;
            int      cy           = current.node.gridPos.y - breath.startPos.y + maxDistance;
            int      currentCost  = breath.travelCost[cx, cy];
            int      currentSteps = breath.steps[cx, cy];
            closedCheck[cx, cy] = true;

            if (currentSteps >= maxDistance)
            {
                continue;
            }

            //shuffle the neighbor nodes to give some noise
            List <HeatmapNode> shuffled = new List <HeatmapNode>();
            foreach (HeatmapNode neighbor in current.node.neighbors)
            {
                shuffled.Insert(Random.Range(0, shuffled.Count), neighbor);
            }

            foreach (HeatmapNode neighbor in shuffled)
            {
                //calculate array position
                int nx = neighbor.gridPos.x - breath.startPos.x + maxDistance;
                int ny = neighbor.gridPos.y - breath.startPos.y + maxDistance;

                //cull disallowed
                if (Vec2I.Max(neighbor.gridPos, breath.startPos) > maxDistance)
                {
                    continue;
                }
                if (closedCheck[nx, ny])
                {
                    continue;
                }
                if (openCheck[nx, ny])
                {
                    continue;
                }
                if (!CanTravel(current.node, neighbor))
                {
                    continue;
                }

                //calculate cost
                int travelCost = current.travelCost + TravelCostBreath(current.node, neighbor);

                //priority sorted by heap
                PathStep step = new PathStep(neighbor, travelCost, 0);
                openList.Add(step);
                openArray[nx, ny] = step;
                openCheck[nx, ny] = true;

                //add breath to area
                breath.exist[nx, ny]      = true;
                breath.parent[nx, ny]     = current.node.gridPos;
                breath.travelCost[nx, ny] = travelCost;
                breath.steps[nx, ny]      = currentSteps + 1;
            }
        }
    }