public VillagerNpc CreateVillager(int x, int y) { Location location = new Location { X = x, Y = y, Z = 0 }; //just skip to the next cell if the location is not empty if (!_map.IsEmptyCell(location)) return null; VillagerNpc villager = new VillagerNpc { Map = _map, Engine = this, Id = _characters.Any() ? _characters.Max(unit => unit.Id) + 1 : 0, Logging = Logging }; _map.Add(villager, location); _characters.Add(villager); //villager.EndMove(location); villager.Ready(new MoveAction { Location = location }); villager.Ready(new IdleAction()); return villager; }
public bool ProcessMove(CharacterBase unit, Location nextLeg) { Debug.WriteLineIf(unit.Id == 0, "Engine: ProcessMove"); if (_unitActionDict.ContainsKey(unit)) { Debug.WriteLineIf(unit.Id == 0, "Engine: ProcessMove returning false"); return false; } return ProcessMoveInternal(unit, nextLeg); }
/// <summary> /// We need an internal ProcessMove method to avoid altering the original path. /// </summary> /// <param name="unit"></param> /// <param name="nextLeg"></param> /// <returns></returns> private bool ProcessMoveInternal(CharacterBase unit, Location nextLeg) { //check that the map is empty at the desired location if (!_map.ReserveIfEmpty(nextLeg, unit)) return false; MoveAction moveAction = new MoveAction { Tick = _timeKeeper.Tick + unit.MovementSpeed, Location = nextLeg }; unit.BeginMove(nextLeg); AddAction(unit, moveAction); return true; }
public bool ReserveIfEmpty(Location location, CharacterBase reservationOwner) { //TODO: move to some constants if will keep it (see below) const int RESERVED = 1; //TODO: maybe set the map id of the unit instead of a reservation code? lock (_mapLockObject) { if (_map[location.X, location.Y] == 0 && 0 == Interlocked.CompareExchange( ref _map[location.X, location.Y], RESERVED, 0)) { //TODO: track the reservation owner return true; } return false; } }
public void Remove(CharacterBase unit, Location location) { _map[location.X, location.Y] = 0; }
public void Move(CharacterBase unit, Location oldLocation, Location newLocation) { _map[oldLocation.X, oldLocation.Y] = 0; _map[newLocation.X, newLocation.Y] = _objectIdDictionary[unit].Id; }
public bool IsEmptyCell(Location location) { if (location.X < 0 || location.Y < 0 || location.X > MAP_WIDTH - 1 || location.Y > MAP_HEIGHT - 1) return false; return _map[location.X, location.Y] == 0; }
public void Add(CharacterBase unit, Location location) { MapIdentifier identifier = _identifierPool.Get(); _objectIdDictionary.Add(unit, identifier); _map[location.X, location.Y] = identifier.Id; }