예제 #1
0
        public QuickSand(ByteVector2 at, Context context) : base(at, context)
        {
            Type           = Constants.Entities.QuickSand.ID;
            VisionDistance = Constants.Entities.QuickSand.VISION;
            HealthCapacity = Constants.Entities.QuickSand.HEALTH;
            HealthPoints   = HealthCapacity;

            _fuseTime        = Constants.Entities.QuickSand.FUSE_TIME;
            _explosionRadius = Constants.Entities.QuickSand.ATTACK_RANGE;
        }
예제 #2
0
        public SonicBomb(ByteVector2 at, Context context) : base(at, context)
        {
            Type           = Constants.Entities.SonicBomb.ID;
            VisionDistance = Constants.Entities.SonicBomb.VISION;
            HealthCapacity = Constants.Entities.SonicBomb.HEALTH;
            HealthPoints   = HealthCapacity;

            _chargeTime = Constants.Entities.SonicBomb.CHARGE_TIME;
            _radius     = Constants.Entities.SonicBomb.REVEAL_RADIUS;
        }
예제 #3
0
        // You can implicitly convert Vector2s to Vector3s
        public ByteVector2[] FindBestPath(ByteVector2 from, ByteVector2 to)
        {
            ByteVector2[] toReturn   = new ByteVector2[0];
            Thread        pathThread = new Thread(() => FindBestPathProcess(ref toReturn, from, to));

            pathThread.Start();
            pathThread.Join();

            return(toReturn);
        }
예제 #4
0
            private void FillGas()
            {
                foreach (Entity e in _emitters)
                {
                    ByteVector2 pos = e.GetPosition();
                    _gasMap[pos.X, pos.Y] = 1;
                }

                for (int r = 0; r < _gasMap.GetLength(0); r++)
                {
                    for (int c = 0; c < _gasMap.GetLength(0); c++)
                    {
                        _fillMap[r, c] = 0;
                    }
                }

                for (int r = 0; r < _gasMap.GetLength(0); r++)
                {
                    for (int c = 0; c < _gasMap.GetLength(0); c++)
                    {
                        double val = _gasMap[r, c];
                        if (val > 0)
                        {
                            FillTile(val, (byte)(r + 1), (byte)(c));
                            FillTile(val, (byte)(r - 1), (byte)(c));
                            FillTile(val, (byte)(r), (byte)(c + 1));
                            FillTile(val, (byte)(r), (byte)(c - 1));
                        }

                        //_gasMap[r, c] = fifth;
                    }
                }

                for (int r = 0; r < _gasMap.GetLength(0); r++)
                {
                    for (int c = 0; c < _gasMap.GetLength(0); c++)
                    {
                        _gasMap[r, c] = _fillMap[r, c];
                    }
                }

                for (int r = 0; r < _gasMap.GetLength(0); r++)
                {
                    for (int c = 0; c < _gasMap.GetLength(0); c++)
                    {
                        _gasMap[r, c] -= Constants.Entities.GasBomb.DECAY_FACTOR;
                        //if (_gasMap[r, c] > Constants.Entities.GasBomb.GAS_MAX)
                        //    _gasMap[r, c] = Constants.Entities.GasBomb.GAS_MAX;
                        if (_gasMap[r, c] < 0)
                        {
                            _gasMap[r, c] = 0;
                        }
                    }
                }
            }
예제 #5
0
        public override bool Deploy(ByteVector2 there, byte inFaction)
        {
            if (!base.Deploy(there, inFaction))
            {
                return(false);
            }

            _job = new HealJob(_interval, _amount, _radius, _context);

            return(true);
        }
예제 #6
0
        public override bool Deploy(ByteVector2 there, byte inFaction)
        {
            if (!base.Deploy(there, inFaction))
            {
                return(false);
            }

            _job = new ReconJob(_chargeTime, _radius, _context);

            return(true);
        }
예제 #7
0
        public override bool Deploy(ByteVector2 there, byte inFaction)
        {
            if (!base.Deploy(there, inFaction))
            {
                return(false);
            }

            _context.MapContext().TileGasManager.RegisterEmitter(this);

            return(true);
        }
예제 #8
0
        private bool ValidMiningState()
        {
            if (ByteVector2.ManhattanDistance(_context.OwnerContext().GetPosition(), _tile) <= 2 && // Miner is "close enough"
                _context.gameManager.MapManager.Map[_tile.X, _tile.Y] > 0)                          // Tile is still solid
            {
                return(true);
            }

            Debug.Log("Faction Manager: Invalid mining job state detected, deleting job");
            return(false);
        }
예제 #9
0
        public AntimatterBomb(ByteVector2 at, Context context) : base(at, context)
        {
            Type           = Constants.Entities.AntimatterBomb.ID;
            VisionDistance = Constants.Entities.AntimatterBomb.VISION;
            HealthCapacity = Constants.Entities.AntimatterBomb.HEALTH;
            HealthPoints   = HealthCapacity;

            _attackDamage    = Constants.Entities.AntimatterBomb.ATTACK_DAMAGE;
            _fuseTime        = Constants.Entities.AntimatterBomb.FUSE_TIME;
            _explosionRadius = Constants.Entities.AntimatterBomb.ATTACK_RANGE;
        }
예제 #10
0
 public void UnlistenAt(Triggerable listener, ByteVector2 position)
 {
     try
     {
         Debug.Log("REMOVING LISTENER : " + listeners[position.X, position.Y].Remove(listener));
     }
     catch (System.Exception e)
     {
         Debug.Log("ERROR REMOVING LISTENER AT ***************************" + e);
     }
 }
예제 #11
0
        public HealStation(ByteVector2 at, Context context) : base(at, context)
        {
            Type           = Constants.Entities.HealStation.ID;
            VisionDistance = Constants.Entities.HealStation.VISION;
            HealthCapacity = Constants.Entities.HealStation.HEALTH;
            HealthPoints   = HealthCapacity;

            _interval = Constants.Entities.HealStation.HEAL_INTERVAL;
            _amount   = Constants.Entities.HealStation.HEAL_AMOUNT;
            _radius   = Constants.Entities.HealStation.HEAL_RADIUS;
        }
예제 #12
0
        public override bool Equals(object obj)
        {
            if (obj.GetType() != typeof(ByteVector2))
            {
                return(false);
            }

            ByteVector2 other = (ByteVector2)obj;

            return(this.X == other.X &&
                   this.Y == other.Y);
        }
예제 #13
0
        public ProximityMine(ByteVector2 at, Context context) : base(at, context)
        {
            Type           = Constants.Entities.ProximityMine.ID;
            VisionDistance = Constants.Entities.ProximityMine.VISION;
            Cloaked        = Constants.Entities.ProximityMine.CLOAKED;
            HealthCapacity = Constants.Entities.ProximityMine.HEALTH;
            HealthPoints   = HealthCapacity;

            _attackDamage    = Constants.Entities.ProximityMine.ATTACK_DAMAGE;
            _fuseTime        = Constants.Entities.ProximityMine.FUSE_TIME;
            _explosionRadius = Constants.Entities.ProximityMine.ATTACK_RANGE;
        }
예제 #14
0
 public void ListenAt(Triggerable listener, ByteVector2 position)
 {
     Debug.Log("TRIG LISTENING");
     try
     {
         listeners[position.X, position.Y].Add(listener);
     }
     catch (System.Exception e)
     {
         Debug.Log("ERROR LISTENING AT ***************************" + e);
     }
 }
예제 #15
0
        public bool Dig(ByteVector2 that)
        {
            if (_context.gameManager.MapManager.Map[that.X, that.Y] == 0) // If the tile at index isn't solid
            {
                return(false);
            }

            _job = new DigJob(that, (float)_attackCooldown, false, _context);

            _status = Constants.Entities.Status.Working;

            return(true);
        }
예제 #16
0
        public Hauler(ByteVector2 at, Context context) : base(at, context)
        {
            Type           = Constants.Entities.Hauler.ID;
            VisionDistance = Constants.Entities.Hauler.VISION;
            HealthCapacity = Constants.Entities.Hauler.HEALTH;
            HealthPoints   = HealthCapacity;
            _moveSpeed     = Constants.Entities.Hauler.SPEED;
            _inventorySize = Constants.Entities.Hauler.INVENTORY;

            _attackDamage   = Constants.Entities.Hauler.ATTACK_DAMAGE;
            _attackCooldown = Constants.Entities.Hauler.ATTACK_INTERVAL;
            _attackRange    = Constants.Entities.Hauler.ATTACK_RANGE;
        }
예제 #17
0
        public ByteVector2[] GetTilesInDiamond(ByteVector2 center, int radius)
        {
            List <ByteVector2> tiles = new List <ByteVector2>();

            int mapSize = Map.GetLength(0);

            int upperX = center.X - radius;

            if (upperX < 0)
            {
                upperX = 0;
            }
            int upperY = center.Y + radius;

            if (upperY >= mapSize)
            {
                upperY = mapSize - 1;
            }

            int lowerX = center.X + radius;

            if (lowerX >= mapSize)
            {
                lowerX = mapSize - 1;
            }
            int lowerY = center.Y - radius;

            if (lowerY < 0)
            {
                lowerY = 0;
            }

            // Upper left
            ByteVector2 start = new ByteVector2((byte)upperX, (byte)upperY);
            // Bottom right
            ByteVector2 end = new ByteVector2((byte)lowerX, (byte)lowerY);

            for (int r = start.Y; r >= end.Y; r--)
            {
                for (int c = start.X; c <= end.X; c++)
                {
                    ByteVector2 addable = new ByteVector2((byte)c, (byte)r);
                    if (ByteVector2.ManhattanDistance(addable, center) <= radius)
                    {
                        tiles.Add(addable);
                    }
                }
            }

            return(tiles.ToArray());
        }
예제 #18
0
        public override bool Deploy(ByteVector2 there, byte inFaction)
        {
            if (!base.Deploy(there, inFaction))
            {
                return(false);
            }

            if (_job == null)
            {
                _job = new SandJob((float)_fuseTime, _explosionRadius, _context);
            }

            return(true);
        }
예제 #19
0
        public virtual void SetPosition(ByteVector2 here)
        {
            // Display in world
            Hidden = false;

            // Update state on tile occupation grid
            _context.gameManager.MapManager.TileOccupationGrid.Move(this, CurrentPosition, here);

            // Update unit state
            CurrentPosition = here;

            // Trigger triggerables
            _context.gameManager.MapManager.TileTriggerGrid.TriggerAt(here, _context.factionID);
        }
예제 #20
0
        public override bool Deploy(ByteVector2 there, byte inFaction)
        {
            if (!base.Deploy(there, inFaction))
            {
                return(false);
            }

            if (_job == null)
            {
                _job = new FuseJob((float)_fuseTime, _attackDamage, _explosionRadius, FuseJob.Shape.Square, _context);
            }

            return(true);
        }
예제 #21
0
        public ByteVector2[] GetPath(ByteVector2 from, ByteVector2 to)
        {
            // Update map
            Pathfinder.SetByteMap(Map);

            if (Map[to.X, to.Y] == Tile.Empty || Map[to.X, to.Y] == Tile.Gas) // EZ case
            {
                return(Pathfinder.FindBestPath(from, to));
            }
            else // The block is solid
            {
                return(Pathfinder.FindBestAdjacentPath(from, to));
            }
        }
예제 #22
0
        // TODO: optimize this somehow
        public void AutoAttack()
        {
            if (_attackTarget != null)
            {
                if (!InRange(_attackTarget, _attackRange) || !_context.MapContext().CheckLOS(CurrentPosition, _attackTarget.GetPosition()))
                {
                    _attackTarget = null;
                }
                else if (_currentAttackCooldown == null)
                {
                    ByteVector2 attackSpot = _attackTarget.GetPosition();
                    Entity[]    toAttack   = _context.MapContext().GetEntities(attackSpot, 0);

                    // Damage nearby
                    foreach (Entity e in toAttack)
                    {
                        if (!e.InFaction(_context.factionID) && e != _attackTarget)
                        {
                            Attack(e);
                        }
                    }

                    if (Attack(_attackTarget))
                    {
                        _currentAttackCooldown = new AttackCooldownJob(_attackCooldown, _context);
                    }
                    else
                    {
                        _attackTarget = null;
                    }
                }
            }
            else
            {
                // Try to find a target
                Entity[] surroundings = _context.gameManager.MapManager.GetEntities(CurrentPosition, _attackRange);
                foreach (Entity e in surroundings)
                {
                    // Only target hostile faction entities
                    if (!e.InFaction(_context.factionID) && !e.InFaction(0) &&
                        ((byte)e.Type <= Constants.Entities.UNIT_IDS || e.Type == Constants.Entities.Hub.ID || e.Type == Constants.Entities.SandBags.ID))
                    {
                        _attackTarget = e;
                        break;
                    }
                }
            }
        }
예제 #23
0
        public bool CheckLOS(ByteVector2 from, ByteVector2 to)
        {
            List <ByteVector2> tiles = GetTilesInLine(from, to);

            foreach (ByteVector2 tile in tiles)
            {
                if (Map[tile.X, tile.Y] == Tile.Empty || Map[tile.X, tile.Y] == Tile.Gas)
                {
                    continue;
                }

                return(false);
            }

            return(true);
        }
예제 #24
0
        public bool InRange(Entity that, int range)
        {
            if (this == that)
            {
                Debug.Log("Server Faction Manager: You're always near yourself dummy!");
                return(true);
            }

            if (that == null)
            {
                Debug.Log("Server Faction Manager: ERROR can't be near null entity.");
                return(false);
            }

            return(ByteVector2.ManhattanDistance(CurrentPosition, that.CurrentPosition) <= range);
        }
예제 #25
0
        // Traces back through nodes from dest. to identify optimal path
        private void SetBestPath(TileNode fromNode)
        {
            LinkedList <ByteVector2> path = new LinkedList <ByteVector2>();
            int length = 0;

            do
            {
                length++;
                // Sort backwards to compensate for 'cavern optimization'
                path.AddLast(new ByteVector2(fromNode.X, fromNode.Y));
                fromNode = fromNode.Parent;
            } while (fromNode != null);

            ByteVector2[] toSet = new ByteVector2[length];
            path.CopyTo(toSet, 0);
            bestPath = toSet;
        }
예제 #26
0
            public void TriggerAt(ByteVector2 position, int triggeringFaction)
            {
                for (int i = 0; i < listeners[position.X, position.Y].Count; i++)
                {
                    Triggerable l = listeners[position.X, position.Y][i];
                    if (l == null)
                    {
                        Debug.Log("ERROR TRIGGERING AT ***************************");
                        continue;
                    }

                    if (!l.InFaction(triggeringFaction)) // Can't trigger own entities
                    {
                        l.Trigger();
                    }
                }
            }
예제 #27
0
        public bool TileInteraction(NewPackets.TileInteraction parameters)
        {
            // Verify index range
            if (parameters.entityIndex >= Entities.Length || parameters.entityIndex < 0)
            {
                return(false);
            }

            // This entity is the actor
            // TODO: reduce casting
            Entity subject = Entities[parameters.entityIndex] as Entity;

            if (subject == null)
            {
                Debug.Log("ERROR: Entity does not exist!");
                return(false);
            }


            ByteVector2 tile = new ByteVector2(parameters.tileX, parameters.tileY);

            // If the entity is `close` to the tile and the tile is solid
            if (MapManager.Map[parameters.tileX, parameters.tileY] != Tile.Empty &&
                ByteVector2.ManhattanDistance(subject.GetPosition(), tile) <= 1)
            {
                // Try to dig with that entity
                IDigger digger = subject as IDigger;
                if (digger != null)
                {
                    digger.Dig(tile);
                }
            }

            // If the entity isn't on that tile
            else if (ByteVector2.ManhattanDistance(subject.GetPosition(), tile) > 0)
            {
                IMover mover = subject as IMover;
                if (mover != null)
                {
                    mover.Move(tile);
                }
            }

            return(true);
        }
예제 #28
0
        // On @on, finds the optimal path @path to one of the tiles adjacent to @to from @from
        // This is useful when selecting a tile for a mining path
        private void FindBestAdjacentPathProcess(ref ByteVector2[] path, ByteVector2 from, ByteVector2 to)
        {
            ByteVector2[] upPath    = new ByteVector2[0];
            ByteVector2[] downPath  = new ByteVector2[0];
            ByteVector2[] leftPath  = new ByteVector2[0];
            ByteVector2[] rightPath = new ByteVector2[0];

            // Fix Me: verify that these lines work since I changed the vector math implementation
            Thread scanUp    = new Thread(() => FindBestPathProcess(ref upPath, from, to + new ByteVector2(0, 1)));
            Thread scanDown  = new Thread(() => FindBestPathProcess(ref downPath, from, to - new ByteVector2(0, 1)));
            Thread scanLeft  = new Thread(() => FindBestPathProcess(ref leftPath, from, to + new ByteVector2(1, 0)));
            Thread scanRight = new Thread(() => FindBestPathProcess(ref rightPath, from, to - new ByteVector2(1, 0)));

            scanUp.Start();
            scanDown.Start();
            scanLeft.Start();
            scanRight.Start();

            scanUp.Join();
            scanDown.Join();
            scanLeft.Join();
            scanRight.Join();

            List <ByteVector2[]> adjacentPaths = new List <ByteVector2[]>(4);

            adjacentPaths.Add(upPath);
            adjacentPaths.Add(downPath);
            adjacentPaths.Add(leftPath);
            adjacentPaths.Add(rightPath);
            adjacentPaths.Sort((a, b) => {
                int aLength = int.MaxValue;
                if (a != null)
                {
                    aLength = a.Length;
                }
                int bLength = int.MaxValue;
                if (b != null)
                {
                    bLength = b.Length;
                }
                return(aLength - bLength);
            });

            path = adjacentPaths[0];
        }
예제 #29
0
        // Scan a single tile, update its state accordingly
        private void AStarScan(ByteVector2 here, TileNode toParent)
        {
            // The tile to scan
            TileNode scanNode = nodeTracker[here.Y, here.X];

            // If the tile is not traversable, ignore
            if (byteMap[here.Y, here.X] != 0)
            {
                return;
            }
            // If the tile is traversable and stateless
            else if (scanNode == null)
            {
                // Initialize and store a new open tile node
                int      heuristic   = EuclideanDistance(here, destination);
                TileNode newOpenNode = new TileNode(here.X, here.Y, toParent.DistanceFromStart + 1, heuristic);
                newOpenNode.Parent          = toParent;
                nodeTracker[here.Y, here.X] = newOpenNode;
                nodeQueue.Enqueue(newOpenNode, newOpenNode.TotalCost);
            }
            // If the tile is closed, ignore
            else if (scanNode.Closed)
            {
                return;
            }
            // If the tile is already open...
            else if (!scanNode.Closed)
            {
                // If new path to this node is better...
                if (scanNode.DistanceFromStart > toParent.DistanceFromStart)
                {
                    // Recalculate total cost and requeue
                    scanNode.DistanceFromStart = toParent.DistanceFromStart + 1;
                    scanNode.RecalculateTotalCost();
                    scanNode.Parent = toParent;
                    nodeQueue.UpdatePriority(scanNode, scanNode.TotalCost);
                }
            }
            else
            {
                Console.WriteLine("Error: invalid tile scan state reached");
            }

            return;
        }
예제 #30
0
        // TODO: move this somewhere nicer pls
        // dear gahd
        public void DamageAllFactionEntities(ByteVector2 from, int radius, int damage)
        {
            for (int j = 0; j < PlayerFactions.Count; j++)
            {
                ServerFactionManager f = PlayerFactions[j];
                for (int i = 0; i < f.Entities.Length; i++)
                {
                    if (f.Entities[i] != null)
                    {
                        //Debug.Log($"Distance was {ByteVector2.Distance(from, f.Entities[i].CurrentPosition)} || radius {radius} || {ByteVector2.Distance(from, f.Entities[i].CurrentPosition) <= (float)radius}");

                        if (ByteVector2.ManhattanDistance(from, f.Entities[i].GetPosition()) <= (float)radius)
                        {
                            f.Entities[i].Damage(damage);
                        }
                    }
                }
            }
        }