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; }
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; }
// 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); }
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; } } } }
public override bool Deploy(ByteVector2 there, byte inFaction) { if (!base.Deploy(there, inFaction)) { return(false); } _job = new HealJob(_interval, _amount, _radius, _context); return(true); }
public override bool Deploy(ByteVector2 there, byte inFaction) { if (!base.Deploy(there, inFaction)) { return(false); } _job = new ReconJob(_chargeTime, _radius, _context); return(true); }
public override bool Deploy(ByteVector2 there, byte inFaction) { if (!base.Deploy(there, inFaction)) { return(false); } _context.MapContext().TileGasManager.RegisterEmitter(this); return(true); }
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); }
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; }
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); } }
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; }
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); }
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; }
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); } }
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); }
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; }
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()); }
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); }
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); }
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); }
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)); } }
// 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; } } } }
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); }
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); }
// 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; }
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(); } } }
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); }
// 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]; }
// 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; }
// 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); } } } } }